diff options
Diffstat (limited to 'arch/arm/plat-omap/omap_device.c')
-rw-r--r-- | arch/arm/plat-omap/omap_device.c | 94 |
1 files changed, 52 insertions, 42 deletions
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 49fc0df0c21f..be45147651cb 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c | |||
@@ -236,61 +236,71 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat) | |||
236 | return 0; | 236 | return 0; |
237 | } | 237 | } |
238 | 238 | ||
239 | static inline struct omap_device *_find_by_pdev(struct platform_device *pdev) | 239 | static void _add_clkdev(struct omap_device *od, const char *clk_alias, |
240 | const char *clk_name) | ||
240 | { | 241 | { |
241 | return container_of(pdev, struct omap_device, pdev); | 242 | struct clk *r; |
243 | struct clk_lookup *l; | ||
244 | |||
245 | if (!clk_alias || !clk_name) | ||
246 | return; | ||
247 | |||
248 | pr_debug("omap_device: %s: Creating %s -> %s\n", | ||
249 | dev_name(&od->pdev.dev), clk_alias, clk_name); | ||
250 | |||
251 | r = clk_get_sys(dev_name(&od->pdev.dev), clk_alias); | ||
252 | if (!IS_ERR(r)) { | ||
253 | pr_warning("omap_device: %s: alias %s already exists\n", | ||
254 | dev_name(&od->pdev.dev), clk_alias); | ||
255 | clk_put(r); | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | r = omap_clk_get_by_name(clk_name); | ||
260 | if (IS_ERR(r)) { | ||
261 | pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n", | ||
262 | dev_name(&od->pdev.dev), clk_name); | ||
263 | return; | ||
264 | } | ||
265 | |||
266 | l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev.dev)); | ||
267 | if (!l) { | ||
268 | pr_err("omap_device: %s: clkdev_alloc for %s failed\n", | ||
269 | dev_name(&od->pdev.dev), clk_alias); | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | clkdev_add(l); | ||
242 | } | 274 | } |
243 | 275 | ||
244 | /** | 276 | /** |
245 | * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks | 277 | * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks |
278 | * and main clock | ||
246 | * @od: struct omap_device *od | 279 | * @od: struct omap_device *od |
280 | * @oh: struct omap_hwmod *oh | ||
247 | * | 281 | * |
248 | * For every optional clock present per hwmod per omap_device, this function | 282 | * For the main clock and every optional clock present per hwmod per |
249 | * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role> | 283 | * omap_device, this function adds an entry in the clkdev table of the |
250 | * if it does not exist already. | 284 | * form <dev-id=dev_name, con-id=role> if it does not exist already. |
251 | * | 285 | * |
252 | * The function is called from inside omap_device_build_ss(), after | 286 | * The function is called from inside omap_device_build_ss(), after |
253 | * omap_device_register. | 287 | * omap_device_register. |
254 | * | 288 | * |
255 | * This allows drivers to get a pointer to its optional clocks based on its role | 289 | * This allows drivers to get a pointer to its optional clocks based on its role |
256 | * by calling clk_get(<dev*>, <role>). | 290 | * by calling clk_get(<dev*>, <role>). |
291 | * In the case of the main clock, a "fck" alias is used. | ||
257 | * | 292 | * |
258 | * No return value. | 293 | * No return value. |
259 | */ | 294 | */ |
260 | static void _add_optional_clock_clkdev(struct omap_device *od, | 295 | static void _add_hwmod_clocks_clkdev(struct omap_device *od, |
261 | struct omap_hwmod *oh) | 296 | struct omap_hwmod *oh) |
262 | { | 297 | { |
263 | int i; | 298 | int i; |
264 | 299 | ||
265 | for (i = 0; i < oh->opt_clks_cnt; i++) { | 300 | _add_clkdev(od, "fck", oh->main_clk); |
266 | struct omap_hwmod_opt_clk *oc; | ||
267 | struct clk *r; | ||
268 | struct clk_lookup *l; | ||
269 | |||
270 | oc = &oh->opt_clks[i]; | ||
271 | |||
272 | if (!oc->_clk) | ||
273 | continue; | ||
274 | |||
275 | r = clk_get_sys(dev_name(&od->pdev.dev), oc->role); | ||
276 | if (!IS_ERR(r)) | ||
277 | continue; /* clkdev entry exists */ | ||
278 | 301 | ||
279 | r = omap_clk_get_by_name((char *)oc->clk); | 302 | for (i = 0; i < oh->opt_clks_cnt; i++) |
280 | if (IS_ERR(r)) { | 303 | _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk); |
281 | pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n", | ||
282 | dev_name(&od->pdev.dev), oc->clk); | ||
283 | continue; | ||
284 | } | ||
285 | |||
286 | l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev)); | ||
287 | if (!l) { | ||
288 | pr_err("omap_device: %s: clkdev_alloc for %s failed\n", | ||
289 | dev_name(&od->pdev.dev), oc->role); | ||
290 | return; | ||
291 | } | ||
292 | clkdev_add(l); | ||
293 | } | ||
294 | } | 304 | } |
295 | 305 | ||
296 | 306 | ||
@@ -316,7 +326,7 @@ u32 omap_device_get_context_loss_count(struct platform_device *pdev) | |||
316 | struct omap_device *od; | 326 | struct omap_device *od; |
317 | u32 ret = 0; | 327 | u32 ret = 0; |
318 | 328 | ||
319 | od = _find_by_pdev(pdev); | 329 | od = to_omap_device(pdev); |
320 | 330 | ||
321 | if (od->hwmods_cnt) | 331 | if (od->hwmods_cnt) |
322 | ret = omap_hwmod_get_context_loss_count(od->hwmods[0]); | 332 | ret = omap_hwmod_get_context_loss_count(od->hwmods[0]); |
@@ -497,7 +507,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | |||
497 | 507 | ||
498 | for (i = 0; i < oh_cnt; i++) { | 508 | for (i = 0; i < oh_cnt; i++) { |
499 | hwmods[i]->od = od; | 509 | hwmods[i]->od = od; |
500 | _add_optional_clock_clkdev(od, hwmods[i]); | 510 | _add_hwmod_clocks_clkdev(od, hwmods[i]); |
501 | } | 511 | } |
502 | 512 | ||
503 | if (ret) | 513 | if (ret) |
@@ -611,7 +621,7 @@ int omap_device_enable(struct platform_device *pdev) | |||
611 | int ret; | 621 | int ret; |
612 | struct omap_device *od; | 622 | struct omap_device *od; |
613 | 623 | ||
614 | od = _find_by_pdev(pdev); | 624 | od = to_omap_device(pdev); |
615 | 625 | ||
616 | if (od->_state == OMAP_DEVICE_STATE_ENABLED) { | 626 | if (od->_state == OMAP_DEVICE_STATE_ENABLED) { |
617 | WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", | 627 | WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", |
@@ -650,7 +660,7 @@ int omap_device_idle(struct platform_device *pdev) | |||
650 | int ret; | 660 | int ret; |
651 | struct omap_device *od; | 661 | struct omap_device *od; |
652 | 662 | ||
653 | od = _find_by_pdev(pdev); | 663 | od = to_omap_device(pdev); |
654 | 664 | ||
655 | if (od->_state != OMAP_DEVICE_STATE_ENABLED) { | 665 | if (od->_state != OMAP_DEVICE_STATE_ENABLED) { |
656 | WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", | 666 | WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", |
@@ -681,7 +691,7 @@ int omap_device_shutdown(struct platform_device *pdev) | |||
681 | int ret, i; | 691 | int ret, i; |
682 | struct omap_device *od; | 692 | struct omap_device *od; |
683 | 693 | ||
684 | od = _find_by_pdev(pdev); | 694 | od = to_omap_device(pdev); |
685 | 695 | ||
686 | if (od->_state != OMAP_DEVICE_STATE_ENABLED && | 696 | if (od->_state != OMAP_DEVICE_STATE_ENABLED && |
687 | od->_state != OMAP_DEVICE_STATE_IDLE) { | 697 | od->_state != OMAP_DEVICE_STATE_IDLE) { |
@@ -722,7 +732,7 @@ int omap_device_align_pm_lat(struct platform_device *pdev, | |||
722 | int ret = -EINVAL; | 732 | int ret = -EINVAL; |
723 | struct omap_device *od; | 733 | struct omap_device *od; |
724 | 734 | ||
725 | od = _find_by_pdev(pdev); | 735 | od = to_omap_device(pdev); |
726 | 736 | ||
727 | if (new_wakeup_lat_limit == od->dev_wakeup_lat) | 737 | if (new_wakeup_lat_limit == od->dev_wakeup_lat) |
728 | return 0; | 738 | return 0; |