aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-10-29 15:51:04 -0400
committerSylwester Nawrocki <s.nawrocki@samsung.com>2013-12-04 11:19:25 -0500
commit4eadfc38c4d6e30775d3764f9a1a3098789d2acc (patch)
treea84b8471f7a311a1a5c3bfe19c116bb783ebf5ab /drivers/media
parent1d9438f7b560862fd0832355b4ad199b30e67478 (diff)
omap3isp: Modify clocks registration to avoid circular references
The clock core code is going to be modified so clk_get() takes reference on the clock provider module. Until the potential circular reference issue is properly addressed, we pass NULL as the first argument to clk_register(), in order to disallow sub-devices taking a reference on the ISP module back trough clk_get(). This should prevent locking the modules in memory. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/omap3isp/isp.c22
-rw-r--r--drivers/media/platform/omap3isp/isp.h1
2 files changed, 17 insertions, 6 deletions
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 1c3608039663..59106623e71e 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -290,9 +290,11 @@ static int isp_xclk_init(struct isp_device *isp)
290 struct clk_init_data init; 290 struct clk_init_data init;
291 unsigned int i; 291 unsigned int i;
292 292
293 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i)
294 isp->xclks[i].clk = ERR_PTR(-EINVAL);
295
293 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { 296 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
294 struct isp_xclk *xclk = &isp->xclks[i]; 297 struct isp_xclk *xclk = &isp->xclks[i];
295 struct clk *clk;
296 298
297 xclk->isp = isp; 299 xclk->isp = isp;
298 xclk->id = i == 0 ? ISP_XCLK_A : ISP_XCLK_B; 300 xclk->id = i == 0 ? ISP_XCLK_A : ISP_XCLK_B;
@@ -305,10 +307,15 @@ static int isp_xclk_init(struct isp_device *isp)
305 init.num_parents = 1; 307 init.num_parents = 1;
306 308
307 xclk->hw.init = &init; 309 xclk->hw.init = &init;
308 310 /*
309 clk = devm_clk_register(isp->dev, &xclk->hw); 311 * The first argument is NULL in order to avoid circular
310 if (IS_ERR(clk)) 312 * reference, as this driver takes reference on the
311 return PTR_ERR(clk); 313 * sensor subdevice modules and the sensors would take
314 * reference on this module through clk_get().
315 */
316 xclk->clk = clk_register(NULL, &xclk->hw);
317 if (IS_ERR(xclk->clk))
318 return PTR_ERR(xclk->clk);
312 319
313 if (pdata->xclks[i].con_id == NULL && 320 if (pdata->xclks[i].con_id == NULL &&
314 pdata->xclks[i].dev_id == NULL) 321 pdata->xclks[i].dev_id == NULL)
@@ -320,7 +327,7 @@ static int isp_xclk_init(struct isp_device *isp)
320 327
321 xclk->lookup->con_id = pdata->xclks[i].con_id; 328 xclk->lookup->con_id = pdata->xclks[i].con_id;
322 xclk->lookup->dev_id = pdata->xclks[i].dev_id; 329 xclk->lookup->dev_id = pdata->xclks[i].dev_id;
323 xclk->lookup->clk = clk; 330 xclk->lookup->clk = xclk->clk;
324 331
325 clkdev_add(xclk->lookup); 332 clkdev_add(xclk->lookup);
326 } 333 }
@@ -335,6 +342,9 @@ static void isp_xclk_cleanup(struct isp_device *isp)
335 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { 342 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
336 struct isp_xclk *xclk = &isp->xclks[i]; 343 struct isp_xclk *xclk = &isp->xclks[i];
337 344
345 if (!IS_ERR(xclk->clk))
346 clk_unregister(xclk->clk);
347
338 if (xclk->lookup) 348 if (xclk->lookup)
339 clkdev_drop(xclk->lookup); 349 clkdev_drop(xclk->lookup);
340 } 350 }
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index ce65d3ae1aa7..d1e857e41731 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -135,6 +135,7 @@ struct isp_xclk {
135 struct isp_device *isp; 135 struct isp_device *isp;
136 struct clk_hw hw; 136 struct clk_hw hw;
137 struct clk_lookup *lookup; 137 struct clk_lookup *lookup;
138 struct clk *clk;
138 enum isp_xclk_id id; 139 enum isp_xclk_id id;
139 140
140 spinlock_t lock; /* Protects enabled and divider */ 141 spinlock_t lock; /* Protects enabled and divider */