diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/tegra/nvavp/nvavp_dev.c | 63 | ||||
-rw-r--r-- | drivers/power/smb349-charger.c | 6 | ||||
-rw-r--r-- | drivers/usb/otg/tegra-otg.c | 9 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 24 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_reg.h | 1 |
5 files changed, 78 insertions, 25 deletions
diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c index 4bea3cb2ab59..012f50b7a5f4 100644 --- a/drivers/media/video/tegra/nvavp/nvavp_dev.c +++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c @@ -107,6 +107,7 @@ struct nvavp_info { u8 *pushbuf_data; u32 pushbuf_index; u32 pushbuf_fence; + bool pending; struct nv_e276_control *os_control; @@ -116,7 +117,7 @@ struct nvavp_info { struct nvhost_device *nvhost_dev; struct miscdevice misc_dev; - atomic_t clock_stay_on_refcount; + atomic_t clock_stay_on_refcount; }; struct nvavp_clientctx { @@ -144,26 +145,29 @@ static struct clk *nvavp_clk_get(struct nvavp_info *nvavp, int id) return NULL; } -static void nvavp_clk_ctrl(struct nvavp_info *nvavp, u32 clk_en) +static void nvavp_clks_enable(struct nvavp_info *nvavp) { - if (clk_en && !nvavp->clk_enabled) { + if (nvavp->clk_enabled++ == 0) { nvhost_module_busy(nvhost_get_host(nvavp->nvhost_dev)->dev); clk_enable(nvavp->bsev_clk); clk_enable(nvavp->vde_clk); clk_set_rate(nvavp->emc_clk, nvavp->emc_clk_rate); clk_set_rate(nvavp->sclk, nvavp->sclk_rate); - nvavp->clk_enabled = 1; dev_dbg(&nvavp->nvhost_dev->dev, "%s: setting sclk to %lu\n", __func__, nvavp->sclk_rate); dev_dbg(&nvavp->nvhost_dev->dev, "%s: setting emc_clk to %lu\n", __func__, nvavp->emc_clk_rate); - } else if (!clk_en && nvavp->clk_enabled) { + } +} + +static void nvavp_clks_disable(struct nvavp_info *nvavp) +{ + if (--nvavp->clk_enabled == 0) { clk_disable(nvavp->bsev_clk); clk_disable(nvavp->vde_clk); clk_set_rate(nvavp->emc_clk, 0); clk_set_rate(nvavp->sclk, 0); nvhost_module_idle(nvhost_get_host(nvavp->nvhost_dev)->dev); - nvavp->clk_enabled = 0; dev_dbg(&nvavp->nvhost_dev->dev, "%s: resetting emc_clk " "and sclk\n", __func__); } @@ -184,7 +188,12 @@ static void clock_disable_handler(struct work_struct *work) clock_disable_work); mutex_lock(&nvavp->pushbuffer_lock); - nvavp_clk_ctrl(nvavp, !nvavp_check_idle(nvavp)); + mutex_lock(&nvavp->open_lock); + if (nvavp_check_idle(nvavp) && nvavp->pending) { + nvavp->pending = false; + nvavp_clks_disable(nvavp); + } + mutex_unlock(&nvavp->open_lock); mutex_unlock(&nvavp->pushbuffer_lock); } @@ -289,27 +298,29 @@ static int nvavp_reset_avp(struct nvavp_info *nvavp, unsigned long reset_addr) static void nvavp_halt_vde(struct nvavp_info *nvavp) { - if (nvavp->clk_enabled) { - tegra_periph_reset_assert(nvavp->bsev_clk); - clk_disable(nvavp->bsev_clk); - tegra_periph_reset_assert(nvavp->vde_clk); - clk_disable(nvavp->vde_clk); - nvhost_module_idle(nvhost_get_host(nvavp->nvhost_dev)->dev); - nvavp->clk_enabled = 0; + if (nvavp->clk_enabled && !nvavp->pending) + BUG(); + + if (nvavp->pending) { + nvavp_clks_disable(nvavp); + nvavp->pending = false; } + + tegra_periph_reset_assert(nvavp->bsev_clk); + tegra_periph_reset_assert(nvavp->vde_clk); } static int nvavp_reset_vde(struct nvavp_info *nvavp) { - if (!nvavp->clk_enabled) - nvhost_module_busy(nvhost_get_host(nvavp->nvhost_dev)->dev); + if (nvavp->clk_enabled) + BUG(); + + nvavp_clks_enable(nvavp); - clk_enable(nvavp->bsev_clk); tegra_periph_reset_assert(nvavp->bsev_clk); udelay(2); tegra_periph_reset_deassert(nvavp->bsev_clk); - clk_enable(nvavp->vde_clk); tegra_periph_reset_assert(nvavp->vde_clk); udelay(2); tegra_periph_reset_deassert(nvavp->vde_clk); @@ -321,7 +332,8 @@ static int nvavp_reset_vde(struct nvavp_info *nvavp) */ clk_set_rate(nvavp->vde_clk, ULONG_MAX); - nvavp->clk_enabled = 1; + nvavp_clks_disable(nvavp); + return 0; } @@ -488,7 +500,12 @@ static int nvavp_pushbuffer_update(struct nvavp_info *nvavp, u32 phys_addr, } /* enable clocks to VDE/BSEV */ - nvavp_clk_ctrl(nvavp, 1); + mutex_lock(&nvavp->open_lock); + if (!nvavp->pending) { + nvavp_clks_enable(nvavp); + nvavp->pending = true; + } + mutex_unlock(&nvavp->open_lock); /* update put pointer */ nvavp->pushbuf_index = (nvavp->pushbuf_index + wordcount) & @@ -1032,14 +1049,14 @@ static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd, struct nvavp_clock_stay_on_state_args clock; if (copy_from_user(&clock, (void __user *)arg, - sizeof(struct nvavp_clock_stay_on_state_args))) + sizeof(struct nvavp_clock_stay_on_state_args))) return -EFAULT; dev_dbg(&nvavp->nvhost_dev->dev, "%s: state=%d\n", __func__, clock.state); if (clock.state != NVAVP_CLOCK_STAY_ON_DISABLED && - clock.state != NVAVP_CLOCK_STAY_ON_ENABLED) { + clock.state != NVAVP_CLOCK_STAY_ON_ENABLED) { dev_err(&nvavp->nvhost_dev->dev, "%s: invalid argument=%d\n", __func__, clock.state); return -EINVAL; @@ -1428,7 +1445,7 @@ static int tegra_nvavp_suspend(struct nvhost_device *ndev, pm_message_t state) mutex_lock(&nvavp->open_lock); if (nvavp->refcount) { - if (nvavp_check_idle(nvavp)) + if (!nvavp->clk_enabled) nvavp_uninit(nvavp); else ret = -EBUSY; diff --git a/drivers/power/smb349-charger.c b/drivers/power/smb349-charger.c index 62d516b374b8..58778409b6ba 100644 --- a/drivers/power/smb349-charger.c +++ b/drivers/power/smb349-charger.c @@ -449,6 +449,11 @@ static int __devinit smb349_probe(struct i2c_client *client, charger->client = client; charger->dev = &client->dev; pdata = client->dev.platform_data; + if(!pdata) { + ret = -ENXIO; + goto error; + } + i2c_set_clientdata(client, charger); /* Check battery presence */ @@ -463,7 +468,6 @@ static int __devinit smb349_probe(struct i2c_client *client, charger->reg_desc.ops = &smb349_tegra_regulator_ops; charger->reg_desc.type = REGULATOR_CURRENT; charger->reg_desc.id = pdata->regulator_id; - charger->reg_desc.type = REGULATOR_CURRENT; charger->reg_desc.owner = THIS_MODULE; charger->reg_init_data.supply_regulator = NULL; diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c index 5258b3ec8992..4c590076f73e 100644 --- a/drivers/usb/otg/tegra-otg.c +++ b/drivers/usb/otg/tegra-otg.c @@ -260,6 +260,15 @@ static void irq_work(struct work_struct *work) else to = OTG_STATE_A_SUSPEND; + if (from != OTG_STATE_A_HOST) { + if (tegra->int_status & USB_VBUS_INT_STATUS) { + if (status & USB_VBUS_STATUS) + to = OTG_STATE_B_PERIPHERAL; + else + to = OTG_STATE_A_SUSPEND; + } + } + spin_unlock_irqrestore(&tegra->lock, flags); tegra_change_otg_state(tegra, to); } diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 935f18bc8cfd..df54578a5b5a 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -2219,6 +2219,26 @@ static void tegra_dc_underflow_handler(struct tegra_dc *dc) dc->ndev->name, (65 + i)); } #endif +#ifdef CONFIG_ARCH_TEGRA_3x_SOC + if (dc->windows[i].underflows > 4) { + printk("%s:dc in underflow state." + " enable UF_LINE_FLUSH to clear up\n", + __func__); + tegra_dc_writel(dc, UF_LINE_FLUSH, + DC_DISP_DISP_MISC_CONTROL); + tegra_dc_writel(dc, GENERAL_UPDATE, + DC_CMD_STATE_CONTROL); + tegra_dc_writel(dc, GENERAL_ACT_REQ, + DC_CMD_STATE_CONTROL); + + tegra_dc_writel(dc, 0, + DC_DISP_DISP_MISC_CONTROL); + tegra_dc_writel(dc, GENERAL_UPDATE, + DC_CMD_STATE_CONTROL); + tegra_dc_writel(dc, GENERAL_ACT_REQ, + DC_CMD_STATE_CONTROL); + } +#endif } else { dc->windows[i].underflows = 0; } @@ -2524,7 +2544,9 @@ static int tegra_dc_init(struct tegra_dc *dc) tegra_dc_writel(dc, 0x0001c700, DC_CMD_INT_POLARITY); tegra_dc_writel(dc, 0x00202020, DC_DISP_MEM_HIGH_PRIORITY); tegra_dc_writel(dc, 0x00010101, DC_DISP_MEM_HIGH_PRIORITY_TIMER); - +#ifdef CONFIG_ARCH_TEGRA_3x_SOC + tegra_dc_writel(dc, 0x00000000, DC_DISP_DISP_MISC_CONTROL); +#endif /* enable interrupts for vblank, frame_end and underflows */ tegra_dc_writel(dc, (FRAME_END_INT | V_BLANK_INT | ALL_UF_INT), DC_CMD_INT_ENABLE); diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h index 5eac27adfbf8..0b628fc7a14a 100644 --- a/drivers/video/tegra/dc/dc_reg.h +++ b/drivers/video/tegra/dc/dc_reg.h @@ -367,6 +367,7 @@ #define DC_DISP_MCCIF_DISPLAY1B_HYST 0x484 #define DC_DISP_DAC_CRT_CTRL 0x4c0 #define DC_DISP_DISP_MISC_CONTROL 0x4c1 +#define UF_LINE_FLUSH (1 << 1) #define DC_WIN_COLOR_PALETTE(x) (0x500 + (x)) |