diff options
| author | Manoj Rao <manojraj@codeaurora.org> | 2013-07-08 23:01:00 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:20:07 -0700 |
| commit | 387f43dba14ba4baddec2e2f0bbf758741b244cf (patch) | |
| tree | 287dd506f45f597aeaa953b11380d36714f84448 /drivers/video/fbdev | |
| parent | b86493137a64f22019c84c0357e87338ea17b8be (diff) | |
msm8974: mhl_sii8334: init chip on discovery
MHL driver initializes the chip in probe and enables
irq. These operations are postponed until they're
required. This prevents any interrupts from
being triggered even when there is no real
communication from hardware. Do not enable
irq wake in suspend before the first discovery
has completed. This ensures wake irq occurs only on
an irq that has been previously allocated.
CRs-Fixed: 509337
Change-Id: Ifa5c66cfe2fb732d2f8e34b7473ab9ae07937dc7
Signed-off-by: Manoj Rao <manojraj@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mhl_sii8334.c | 114 |
1 files changed, 48 insertions, 66 deletions
diff --git a/drivers/video/fbdev/msm/mhl_sii8334.c b/drivers/video/fbdev/msm/mhl_sii8334.c index b6f2737193aa..40c71485890b 100644 --- a/drivers/video/fbdev/msm/mhl_sii8334.c +++ b/drivers/video/fbdev/msm/mhl_sii8334.c @@ -357,14 +357,20 @@ static int mhl_sii_reset_pin(struct mhl_tx_ctrl *mhl_ctrl, int on) static int mhl_sii_wait_for_rgnd(struct mhl_tx_ctrl *mhl_ctrl) { int timeout; - /* let isr handle RGND interrupt */ + pr_debug("%s:%u\n", __func__, __LINE__); INIT_COMPLETION(mhl_ctrl->rgnd_done); + /* + * after toggling reset line and enabling disc + * tx can take a while to generate intr + */ timeout = wait_for_completion_interruptible_timeout - (&mhl_ctrl->rgnd_done, HZ); + (&mhl_ctrl->rgnd_done, HZ * 3); if (!timeout) { - /* most likely nothing plugged in USB */ - /* USB HOST connected or already in USB mode */ + /* + * most likely nothing plugged in USB + * USB HOST connected or already in USB mode + */ pr_warn("%s:%u timedout\n", __func__, __LINE__); return -ENODEV; } @@ -380,9 +386,25 @@ static int mhl_sii_device_discovery(void *data, int id, struct i2c_client *client = mhl_ctrl->i2c_handle; unsigned long flags; - enable_irq(client->irq); + if (!mhl_ctrl->irq_req_done) { + rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL, + &mhl_tx_isr, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + client->dev.driver->name, mhl_ctrl); + if (rc) { + pr_err("request_threaded_irq failed, status: %d\n", + rc); + return -EINVAL; + } else { + pr_debug("request_threaded_irq succeeded\n"); + mhl_ctrl->irq_req_done = true; + } + } else { + enable_irq(client->irq); + } + /* wait for i2c interrupt line to be activated */ - msleep(300); + msleep(100); if (id) { /* When MHL cable is disconnected we get a sii8334 @@ -413,8 +435,10 @@ static int mhl_sii_device_discovery(void *data, int id, /* chipset PR recommends waiting for at least 100 ms * the chipset needs longer to come out of D3 state. */ - msleep(300); + msleep(100); mhl_init_reg_settings(mhl_ctrl, true); + /* allow tx to enable dev disc after D3 state */ + msleep(100); rc = mhl_sii_wait_for_rgnd(mhl_ctrl); } else { if (mhl_ctrl->cur_state == POWER_STATE_D3) { @@ -493,6 +517,10 @@ static void cbus_reset(struct mhl_tx_ctrl *mhl_ctrl) uint8_t i; struct i2c_client *client = mhl_ctrl->i2c_handle; + /* Read the chip rev ID */ + mhl_ctrl->chip_rev_id = MHL_SII_PAGE0_RD(0x04); + pr_debug("MHL: chip rev ID read=[%x]\n", mhl_ctrl->chip_rev_id); + /* * REG_SRST */ @@ -1423,40 +1451,6 @@ static irqreturn_t mhl_tx_isr(int irq, void *data) return IRQ_HANDLED; } -static int mhl_tx_chip_init(struct mhl_tx_ctrl *mhl_ctrl) -{ - uint8_t chip_rev_id = 0x00; - struct i2c_client *client = mhl_ctrl->i2c_handle; - unsigned long flags; - - - spin_lock_irqsave(&mhl_ctrl->lock, flags); - mhl_ctrl->dwnstream_hpd = 0; - mhl_ctrl->tx_powered_off = false; - spin_unlock_irqrestore(&mhl_ctrl->lock, flags); - - /* Reset the TX chip */ - mhl_sii_reset_pin(mhl_ctrl, 0); - msleep(20); - mhl_sii_reset_pin(mhl_ctrl, 1); - /* TX PR-guide requires a 100 ms wait here */ - msleep(100); - - /* Read the chip rev ID */ - chip_rev_id = MHL_SII_PAGE0_RD(0x04); - pr_debug("MHL: chip rev ID read=[%x]\n", chip_rev_id); - mhl_ctrl->chip_rev_id = chip_rev_id; - - /* - * Need to disable MHL discovery if - * MHL-USB handshake is implemented - */ - mhl_init_reg_settings(mhl_ctrl, true); - switch_mode(mhl_ctrl, POWER_STATE_D3, true); - pr_debug("%s:%u: power_down\n", __func__, __LINE__); - mhl_tx_down(mhl_ctrl); - return 0; -} static int mhl_sii_reg_config(struct i2c_client *client, bool enable) { @@ -1786,30 +1780,12 @@ static int mhl_i2c_probe(struct i2c_client *client, } } - rc = mhl_tx_chip_init(mhl_ctrl); - if (rc) { - pr_err("%s: tx chip init failed [%d]\n", - __func__, rc); - goto failed_probe; - } + mhl_ctrl->dwnstream_hpd = 0; + mhl_ctrl->tx_powered_off = false; + init_completion(&mhl_ctrl->rgnd_done); - pr_debug("%s: IRQ from GPIO INTR = %d\n", - __func__, mhl_ctrl->i2c_handle->irq); - pr_debug("%s: Driver name = [%s]\n", __func__, - client->dev.driver->name); - rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL, - &mhl_tx_isr, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - client->dev.driver->name, mhl_ctrl); - if (rc) { - pr_err("request_threaded_irq failed, status: %d\n", - rc); - goto failed_probe; - } else { - pr_debug("request_threaded_irq succeeded\n"); - } mhl_ctrl->mhl_psy.name = "ext-vbus"; mhl_ctrl->mhl_psy.type = POWER_SUPPLY_TYPE_USB_DCP; @@ -1935,15 +1911,21 @@ MODULE_DEVICE_TABLE(i2c, mhl_sii_i2c_id); #if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP) static int mhl_i2c_suspend_sub(struct i2c_client *client) { - enable_irq_wake(client->irq); - disable_irq(client->irq); + struct mhl_tx_ctrl *mhl_ctrl = i2c_get_clientdata(client); + + if (mhl_ctrl->irq_req_done) { + enable_irq_wake(client->irq); + disable_irq(client->irq); + } return 0; } static int mhl_i2c_resume_sub(struct i2c_client *client) { - disable_irq_wake(client->irq); - enable_irq(client->irq); + struct mhl_tx_ctrl *mhl_ctrl = i2c_get_clientdata(client); + + if (mhl_ctrl->irq_req_done) + disable_irq_wake(client->irq); return 0; } #endif /* defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP) */ |
