From ccaddfe1a2e10f50aa6f553f9791c2724b6d3c4a Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 30 Jul 2013 11:35:03 +0300 Subject: drm/tegra: hdmi: Make sure clock is enabled before dumping registers The debugfs register dumping function did not enable the HDMI clock. This led to a possible system hang when reading the debugfs entry while no HDMI cable was connected to the system. This patch makes sure that the clock is enabled during the read. Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c index 01097da..bf7f027 100644 --- a/drivers/gpu/host1x/drm/hdmi.c +++ b/drivers/gpu/host1x/drm/hdmi.c @@ -904,6 +904,11 @@ static int tegra_hdmi_show_regs(struct seq_file *s, void *data) { struct drm_info_node *node = s->private; struct tegra_hdmi *hdmi = node->info_ent->data; + int err; + + err = clk_enable(hdmi->clk); + if (err) + return err; #define DUMP_REG(name) \ seq_printf(s, "%-56s %#05x %08lx\n", #name, name, \ @@ -1069,6 +1074,8 @@ static int tegra_hdmi_show_regs(struct seq_file *s, void *data) #undef DUMP_REG + clk_disable(hdmi->clk); + return 0; } -- cgit v0.10.2 From f5fda676e9a3991aab159418f870351bc7d45d96 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Aug 2013 13:18:25 +0300 Subject: gpu: host1x: fix an integer overflow check Tegra is a 32 bit arch. On 32 bit systems then size_t is 32 bits so "total" will never be higher than UINT_MAX because of integer overflows. We need cast to u64 first before doing the math. Also the addition earlier: unsigned int num_unpins = num_cmdbufs + num_relocs; That can overflow as well, but I think it's still safe because we check both "num_cmdbufs" and "num_relocs" again in this test. Signed-off-by: Dan Carpenter Signed-off-by: Thierry Reding diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index cc80766..18a47f9 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -42,12 +42,12 @@ struct host1x_job *host1x_job_alloc(struct host1x_channel *ch, /* Check that we're not going to overflow */ total = sizeof(struct host1x_job) + - num_relocs * sizeof(struct host1x_reloc) + - num_unpins * sizeof(struct host1x_job_unpin_data) + - num_waitchks * sizeof(struct host1x_waitchk) + - num_cmdbufs * sizeof(struct host1x_job_gather) + - num_unpins * sizeof(dma_addr_t) + - num_unpins * sizeof(u32 *); + (u64)num_relocs * sizeof(struct host1x_reloc) + + (u64)num_unpins * sizeof(struct host1x_job_unpin_data) + + (u64)num_waitchks * sizeof(struct host1x_waitchk) + + (u64)num_cmdbufs * sizeof(struct host1x_job_gather) + + (u64)num_unpins * sizeof(dma_addr_t) + + (u64)num_unpins * sizeof(u32 *); if (total > ULONG_MAX) return NULL; -- cgit v0.10.2 From 745cecc07cee878a5afdda40d13f8b0901a88ebd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Aug 2013 13:19:11 +0300 Subject: gpu: host1x: returning success instead of -ENOMEM There is a mistake here so it returns PTR_ERR(NULL) which is success instead of -ENOMEM. Signed-off-by: Dan Carpenter Signed-off-by: Thierry Reding diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index 18a47f9..c4e1050 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -466,9 +466,8 @@ static inline int copy_gathers(struct host1x_job *job, struct device *dev) &job->gather_copy, GFP_KERNEL); if (!job->gather_copy_mapped) { - int err = PTR_ERR(job->gather_copy_mapped); job->gather_copy_mapped = NULL; - return err; + return -ENOMEM; } job->gather_copy_size = size; -- cgit v0.10.2 From 03c961ba6d04786c8a7e7df118538a01f442e90b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 3 Sep 2013 08:50:39 +0200 Subject: gpu: host1x: Check for valid host1x pointer Under rare circumstances it can happen that the host1x driver's .probe() doesn't finish properly, in which case the device's driver-specific data will not be set. Instead of crashing in such a situation, propagate the error to callers of the host1x_get_drm_data() function. Signed-off-by: Thierry Reding diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 28e28a2..4716302 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -43,7 +43,7 @@ void host1x_set_drm_data(struct device *dev, void *data) void *host1x_get_drm_data(struct device *dev) { struct host1x *host1x = dev_get_drvdata(dev); - return host1x->drm_data; + return host1x ? host1x->drm_data : NULL; } void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r) -- cgit v0.10.2 From 57c6eb6f2cf89baef4188b4257b3e756f9aebef4 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 3 Sep 2013 09:02:22 +0200 Subject: gpu: host1x: Sort drivers by probe order External driver declarations are sorted by probe order for consistency. Signed-off-by: Thierry Reding diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h index 790ddf1..bed90a8 100644 --- a/drivers/gpu/host1x/dev.h +++ b/drivers/gpu/host1x/dev.h @@ -301,8 +301,8 @@ static inline void host1x_hw_show_mlocks(struct host1x *host, struct output *o) host->debug_op->show_mlocks(host, o); } -extern struct platform_driver tegra_hdmi_driver; extern struct platform_driver tegra_dc_driver; +extern struct platform_driver tegra_hdmi_driver; extern struct platform_driver tegra_gr2d_driver; #endif -- cgit v0.10.2 From 03da0e7ba9e3a1fc700f60913ff6bcb19f7eac2a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 30 Aug 2013 15:27:16 +0200 Subject: drm/tegra: Parse device tree earlier Parsing the device tree may cause probing to be deferred. Doing this as early as possible prevents any other resources from being requested and enabled, therefore reducing the need to cleanup on deferred probe while at the same time not wasting precious CPU cycles determining if probing needs to be deferred or not. Signed-off-by: Thierry Reding diff --git a/drivers/gpu/host1x/drm/rgb.c b/drivers/gpu/host1x/drm/rgb.c index ed4416f..5aa66ef 100644 --- a/drivers/gpu/host1x/drm/rgb.c +++ b/drivers/gpu/host1x/drm/rgb.c @@ -147,6 +147,13 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc) if (!rgb) return -ENOMEM; + rgb->output.dev = dc->dev; + rgb->output.of_node = np; + + err = tegra_output_parse_dt(&rgb->output); + if (err < 0) + return err; + rgb->clk = devm_clk_get(dc->dev, NULL); if (IS_ERR(rgb->clk)) { dev_err(dc->dev, "failed to get clock\n"); @@ -165,13 +172,6 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc) return err; } - rgb->output.dev = dc->dev; - rgb->output.of_node = np; - - err = tegra_output_parse_dt(&rgb->output); - if (err < 0) - return err; - dc->rgb = &rgb->output; return 0; -- cgit v0.10.2