summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/tegra/nvavp/nvavp_dev.c63
-rw-r--r--drivers/power/smb349-charger.c6
-rw-r--r--drivers/usb/otg/tegra-otg.c9
-rw-r--r--drivers/video/tegra/dc/dc.c24
-rw-r--r--drivers/video/tegra/dc/dc_reg.h1
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))