aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/omap_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/omap_device.c')
-rw-r--r--arch/arm/plat-omap/omap_device.c110
1 files changed, 68 insertions, 42 deletions
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index d2b160942ccc..abe933cd8f09 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -82,6 +82,7 @@
82#include <linux/slab.h> 82#include <linux/slab.h>
83#include <linux/err.h> 83#include <linux/err.h>
84#include <linux/io.h> 84#include <linux/io.h>
85#include <linux/clk.h>
85 86
86#include <plat/omap_device.h> 87#include <plat/omap_device.h>
87#include <plat/omap_hwmod.h> 88#include <plat/omap_hwmod.h>
@@ -90,12 +91,6 @@
90#define USE_WAKEUP_LAT 0 91#define USE_WAKEUP_LAT 0
91#define IGNORE_WAKEUP_LAT 1 92#define IGNORE_WAKEUP_LAT 1
92 93
93/*
94 * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
95 * obtained via container_of() is in fact a struct omap_device
96 */
97#define OMAP_DEVICE_MAGIC 0xf00dcafe
98
99/* Private functions */ 94/* Private functions */
100 95
101/** 96/**
@@ -243,6 +238,44 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
243 return container_of(pdev, struct omap_device, pdev); 238 return container_of(pdev, struct omap_device, pdev);
244} 239}
245 240
241/**
242 * _add_optional_clock_alias - Add clock alias for hwmod optional clocks
243 * @od: struct omap_device *od
244 *
245 * For every optional clock present per hwmod per omap_device, this function
246 * adds an entry in the clocks list of the form <dev-id=dev_name, con-id=role>
247 * if an entry is already present in it with the form <dev-id=NULL, con-id=role>
248 *
249 * The function is called from inside omap_device_build_ss(), after
250 * omap_device_register.
251 *
252 * This allows drivers to get a pointer to its optional clocks based on its role
253 * by calling clk_get(<dev*>, <role>).
254 *
255 * No return value.
256 */
257static void _add_optional_clock_alias(struct omap_device *od,
258 struct omap_hwmod *oh)
259{
260 int i;
261
262 for (i = 0; i < oh->opt_clks_cnt; i++) {
263 struct omap_hwmod_opt_clk *oc;
264 int r;
265
266 oc = &oh->opt_clks[i];
267
268 if (!oc->_clk)
269 continue;
270
271 r = clk_add_alias(oc->role, dev_name(&od->pdev.dev),
272 (char *)oc->clk, &od->pdev.dev);
273 if (r)
274 pr_err("omap_device: %s: clk_add_alias for %s failed\n",
275 dev_name(&od->pdev.dev), oc->role);
276 }
277}
278
246 279
247/* Public functions for use by core code */ 280/* Public functions for use by core code */
248 281
@@ -257,12 +290,11 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
257 */ 290 */
258int omap_device_count_resources(struct omap_device *od) 291int omap_device_count_resources(struct omap_device *od)
259{ 292{
260 struct omap_hwmod *oh;
261 int c = 0; 293 int c = 0;
262 int i; 294 int i;
263 295
264 for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) 296 for (i = 0; i < od->hwmods_cnt; i++)
265 c += omap_hwmod_count_resources(oh); 297 c += omap_hwmod_count_resources(od->hwmods[i]);
266 298
267 pr_debug("omap_device: %s: counted %d total resources across %d " 299 pr_debug("omap_device: %s: counted %d total resources across %d "
268 "hwmods\n", od->pdev.name, c, od->hwmods_cnt); 300 "hwmods\n", od->pdev.name, c, od->hwmods_cnt);
@@ -289,12 +321,11 @@ int omap_device_count_resources(struct omap_device *od)
289 */ 321 */
290int omap_device_fill_resources(struct omap_device *od, struct resource *res) 322int omap_device_fill_resources(struct omap_device *od, struct resource *res)
291{ 323{
292 struct omap_hwmod *oh;
293 int c = 0; 324 int c = 0;
294 int i, r; 325 int i, r;
295 326
296 for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) { 327 for (i = 0; i < od->hwmods_cnt; i++) {
297 r = omap_hwmod_fill_resources(oh, res); 328 r = omap_hwmod_fill_resources(od->hwmods[i], res);
298 res += r; 329 res += r;
299 c += r; 330 c += r;
300 } 331 }
@@ -414,15 +445,15 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
414 od->pm_lats = pm_lats; 445 od->pm_lats = pm_lats;
415 od->pm_lats_cnt = pm_lats_cnt; 446 od->pm_lats_cnt = pm_lats_cnt;
416 447
417 od->magic = OMAP_DEVICE_MAGIC;
418
419 if (is_early_device) 448 if (is_early_device)
420 ret = omap_early_device_register(od); 449 ret = omap_early_device_register(od);
421 else 450 else
422 ret = omap_device_register(od); 451 ret = omap_device_register(od);
423 452
424 for (i = 0; i < oh_cnt; i++) 453 for (i = 0; i < oh_cnt; i++) {
425 hwmods[i]->od = od; 454 hwmods[i]->od = od;
455 _add_optional_clock_alias(od, hwmods[i]);
456 }
426 457
427 if (ret) 458 if (ret)
428 goto odbs_exit4; 459 goto odbs_exit4;
@@ -473,6 +504,7 @@ int omap_device_register(struct omap_device *od)
473{ 504{
474 pr_debug("omap_device: %s: registering\n", od->pdev.name); 505 pr_debug("omap_device: %s: registering\n", od->pdev.name);
475 506
507 od->pdev.dev.parent = &omap_device_parent;
476 return platform_device_register(&od->pdev); 508 return platform_device_register(&od->pdev);
477} 509}
478 510
@@ -566,7 +598,6 @@ int omap_device_shutdown(struct platform_device *pdev)
566{ 598{
567 int ret, i; 599 int ret, i;
568 struct omap_device *od; 600 struct omap_device *od;
569 struct omap_hwmod *oh;
570 601
571 od = _find_by_pdev(pdev); 602 od = _find_by_pdev(pdev);
572 603
@@ -579,8 +610,8 @@ int omap_device_shutdown(struct platform_device *pdev)
579 610
580 ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT); 611 ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT);
581 612
582 for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) 613 for (i = 0; i < od->hwmods_cnt; i++)
583 omap_hwmod_shutdown(oh); 614 omap_hwmod_shutdown(od->hwmods[i]);
584 615
585 od->_state = OMAP_DEVICE_STATE_SHUTDOWN; 616 od->_state = OMAP_DEVICE_STATE_SHUTDOWN;
586 617
@@ -627,18 +658,6 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
627} 658}
628 659
629/** 660/**
630 * omap_device_is_valid - Check if pointer is a valid omap_device
631 * @od: struct omap_device *
632 *
633 * Return whether struct omap_device pointer @od points to a valid
634 * omap_device.
635 */
636bool omap_device_is_valid(struct omap_device *od)
637{
638 return (od && od->magic == OMAP_DEVICE_MAGIC);
639}
640
641/**
642 * omap_device_get_pwrdm - return the powerdomain * associated with @od 661 * omap_device_get_pwrdm - return the powerdomain * associated with @od
643 * @od: struct omap_device * 662 * @od: struct omap_device *
644 * 663 *
@@ -692,11 +711,10 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od)
692 */ 711 */
693int omap_device_enable_hwmods(struct omap_device *od) 712int omap_device_enable_hwmods(struct omap_device *od)
694{ 713{
695 struct omap_hwmod *oh;
696 int i; 714 int i;
697 715
698 for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) 716 for (i = 0; i < od->hwmods_cnt; i++)
699 omap_hwmod_enable(oh); 717 omap_hwmod_enable(od->hwmods[i]);
700 718
701 /* XXX pass along return value here? */ 719 /* XXX pass along return value here? */
702 return 0; 720 return 0;
@@ -710,11 +728,10 @@ int omap_device_enable_hwmods(struct omap_device *od)
710 */ 728 */
711int omap_device_idle_hwmods(struct omap_device *od) 729int omap_device_idle_hwmods(struct omap_device *od)
712{ 730{
713 struct omap_hwmod *oh;
714 int i; 731 int i;
715 732
716 for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) 733 for (i = 0; i < od->hwmods_cnt; i++)
717 omap_hwmod_idle(oh); 734 omap_hwmod_idle(od->hwmods[i]);
718 735
719 /* XXX pass along return value here? */ 736 /* XXX pass along return value here? */
720 return 0; 737 return 0;
@@ -729,11 +746,10 @@ int omap_device_idle_hwmods(struct omap_device *od)
729 */ 746 */
730int omap_device_disable_clocks(struct omap_device *od) 747int omap_device_disable_clocks(struct omap_device *od)
731{ 748{
732 struct omap_hwmod *oh;
733 int i; 749 int i;
734 750
735 for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) 751 for (i = 0; i < od->hwmods_cnt; i++)
736 omap_hwmod_disable_clocks(oh); 752 omap_hwmod_disable_clocks(od->hwmods[i]);
737 753
738 /* XXX pass along return value here? */ 754 /* XXX pass along return value here? */
739 return 0; 755 return 0;
@@ -748,12 +764,22 @@ int omap_device_disable_clocks(struct omap_device *od)
748 */ 764 */
749int omap_device_enable_clocks(struct omap_device *od) 765int omap_device_enable_clocks(struct omap_device *od)
750{ 766{
751 struct omap_hwmod *oh;
752 int i; 767 int i;
753 768
754 for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) 769 for (i = 0; i < od->hwmods_cnt; i++)
755 omap_hwmod_enable_clocks(oh); 770 omap_hwmod_enable_clocks(od->hwmods[i]);
756 771
757 /* XXX pass along return value here? */ 772 /* XXX pass along return value here? */
758 return 0; 773 return 0;
759} 774}
775
776struct device omap_device_parent = {
777 .init_name = "omap",
778 .parent = &platform_bus,
779};
780
781static int __init omap_device_init(void)
782{
783 return device_register(&omap_device_parent);
784}
785core_initcall(omap_device_init);