static int tegra_dc_remove(struct nvhost_device *ndev) { struct tegra_dc *dc = nvhost_get_drvdata(ndev); if (dc->fb) { tegra_fb_unregister(dc->fb); if (dc->fb_mem) release_resource(dc->fb_mem); } tegra_dc_ext_disable(dc->ext); if (dc->ext) tegra_dc_ext_unregister(dc->ext); if (dc->enabled) _tegra_dc_disable(dc); free_irq(dc->irq, dc); clk_put(dc->emc_clk); clk_put(dc->clk); iounmap(dc->base); if (dc->fb_mem) release_resource(dc->base_res); kfree(dc); return 0; }
static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state) { struct tegra_dc *dc = nvhost_get_drvdata(ndev); trace_printk("%s:suspend\n", dc->ndev->name); dev_info(&ndev->dev, "suspend\n"); tegra_dc_ext_disable(dc->ext); mutex_lock(&dc->lock); if (dc->out_ops && dc->out_ops->suspend) dc->out_ops->suspend(dc); if (dc->enabled) { _tegra_dc_disable(dc); dc->suspended = true; } if (dc->out && dc->out->postsuspend) { dc->out->postsuspend(); if (dc->out->type && dc->out->type == TEGRA_DC_OUT_HDMI) /* * avoid resume event due to voltage falling */ msleep(100); } mutex_unlock(&dc->lock); return 0; }
static int tegra_dc_remove(struct nvhost_device *ndev) { struct tegra_dc *dc = nvhost_get_drvdata(ndev); tegra_dc_remove_sysfs(&dc->ndev->dev); tegra_dc_remove_debugfs(dc); if (dc->fb) { tegra_fb_unregister(dc->fb); if (dc->fb_mem) release_resource(dc->fb_mem); } tegra_dc_ext_disable(dc->ext); if (dc->ext) tegra_dc_ext_unregister(dc->ext); if (dc->enabled) _tegra_dc_disable(dc); #ifdef CONFIG_SWITCH switch_dev_unregister(&dc->modeset_switch); #endif free_irq(dc->irq, dc); clk_put(dc->emc_clk); clk_put(dc->clk); iounmap(dc->base); if (dc->fb_mem) release_resource(dc->base_res); kfree(dc); tegra_dc_set(NULL, ndev->id); return 0; }
void tegra_dc_disable(struct tegra_dc *dc) { tegra_dc_ext_disable(dc->ext); /* it's important that new underflow work isn't scheduled before the * lock is acquired. */ cancel_delayed_work_sync(&dc->underflow_work); if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) { mutex_lock(&dc->one_shot_lock); cancel_delayed_work_sync(&dc->one_shot_work); } mutex_lock(&dc->lock); if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_LP_MODE) tegra_dc_host_resume(dc); if (dc->enabled) { dc->enabled = false; if (!dc->suspended) _tegra_dc_disable(dc); } #ifdef CONFIG_SWITCH switch_set_state(&dc->modeset_switch, 0); #endif mutex_unlock(&dc->lock); if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) mutex_unlock(&dc->one_shot_lock); print_mode_info(dc, dc->mode); }
static void tegra_dc_reset_worker(struct work_struct *work) { struct tegra_dc *dc = container_of(work, struct tegra_dc, reset_work); unsigned long val = 0; mutex_lock(&shared_lock); dev_warn(&dc->ndev->dev, "overlay stuck in underflow state. resetting.\n"); tegra_dc_ext_disable(dc->ext); mutex_lock(&dc->lock); if (dc->enabled == false) goto unlock; dc->enabled = false; /* * off host read bus */ val = tegra_dc_readl(dc, DC_CMD_CONT_SYNCPT_VSYNC); val &= ~(0x00000100); tegra_dc_writel(dc, val, DC_CMD_CONT_SYNCPT_VSYNC); /* * set DC to STOP mode */ tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND); msleep(10); _tegra_dc_controller_disable(dc); /* _tegra_dc_controller_reset_enable deasserts reset */ _tegra_dc_controller_reset_enable(dc); dc->enabled = true; /* reopen host read bus */ val = tegra_dc_readl(dc, DC_CMD_CONT_SYNCPT_VSYNC); val &= ~(0x00000100); val |= 0x100; tegra_dc_writel(dc, val, DC_CMD_CONT_SYNCPT_VSYNC); unlock: mutex_unlock(&dc->lock); mutex_unlock(&shared_lock); trace_printk("%s:reset complete\n", dc->ndev->name); }
void tegra_dc_disable(struct tegra_dc *dc) { tegra_dc_ext_disable(dc->ext); mutex_lock(&dc->lock); if (dc->enabled) { dc->enabled = false; _tegra_dc_disable(dc); } mutex_unlock(&dc->lock); }
static void tegra_dc_reset_worker(struct work_struct *work) { struct tegra_dc *dc = container_of(work, struct tegra_dc, reset_work); dev_warn(&dc->ndev->dev, "overlay stuck in underflow state. resetting.\n"); tegra_dc_ext_disable(dc->ext); mutex_lock(&dc->lock); _tegra_dc_disable(dc); msleep(100); tegra_periph_reset_assert(dc->clk); /* _tegra_dc_enable deasserts reset */ _tegra_dc_enable(dc); mutex_unlock(&dc->lock); }
static int tegra_dc_suspend(struct nvhost_device *ndev, pm_message_t state) { struct tegra_dc *dc = nvhost_get_drvdata(ndev); dev_info(&ndev->dev, "suspend\n"); tegra_dc_ext_disable(dc->ext); mutex_lock(&dc->lock); if (dc->out_ops && dc->out_ops->suspend) dc->out_ops->suspend(dc); if (dc->enabled) { _tegra_dc_disable(dc); } if (dc->out && dc->out->postsuspend) dc->out->postsuspend(); mutex_unlock(&dc->lock); return 0; }
void tegra_dc_disable(struct tegra_dc *dc) { tegra_dc_ext_disable(dc->ext); /* it's important that new underflow work isn't scheduled before the * lock is acquired. */ cancel_delayed_work_sync(&dc->underflow_work); mutex_lock(&dc->lock); if (dc->enabled) { dc->enabled = false; if (!dc->suspended) _tegra_dc_disable(dc); } #ifdef CONFIG_SWITCH switch_set_state(&dc->modeset_switch, 0); #endif mutex_unlock(&dc->lock); print_mode_info(dc, dc->mode); }