diff options
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 115 |
1 files changed, 67 insertions, 48 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 241c663a8f62..f74f3af95cae 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -169,6 +169,29 @@ static struct omap_hwmod *mpu_oh; | |||
169 | /* Private functions */ | 169 | /* Private functions */ |
170 | 170 | ||
171 | /** | 171 | /** |
172 | * _fetch_next_ocp_if - return @i'th OCP interface in an array | ||
173 | * @p: ptr to a ptr to the list_head inside the ocp_if to return (not yet used) | ||
174 | * @old: ptr to an array of struct omap_hwmod_ocp_if records | ||
175 | * @i: pointer to the index into the @old array | ||
176 | * | ||
177 | * Return a pointer to the next struct omap_hwmod_ocp_if record in a | ||
178 | * sequence. Currently returns a struct omap_hwmod_ocp_if record | ||
179 | * corresponding to the element index pointed to by @i in the @old | ||
180 | * array, and increments the index pointed to by @i. | ||
181 | */ | ||
182 | static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p, | ||
183 | struct omap_hwmod_ocp_if **old, | ||
184 | int *i) | ||
185 | { | ||
186 | struct omap_hwmod_ocp_if *oi; | ||
187 | |||
188 | oi = old[*i]; | ||
189 | *i = *i + 1; | ||
190 | |||
191 | return oi; | ||
192 | } | ||
193 | |||
194 | /** | ||
172 | * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy | 195 | * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy |
173 | * @oh: struct omap_hwmod * | 196 | * @oh: struct omap_hwmod * |
174 | * | 197 | * |
@@ -582,16 +605,13 @@ static int _init_main_clk(struct omap_hwmod *oh) | |||
582 | */ | 605 | */ |
583 | static int _init_interface_clks(struct omap_hwmod *oh) | 606 | static int _init_interface_clks(struct omap_hwmod *oh) |
584 | { | 607 | { |
608 | struct omap_hwmod_ocp_if *os; | ||
585 | struct clk *c; | 609 | struct clk *c; |
586 | int i; | 610 | int i = 0; |
587 | int ret = 0; | 611 | int ret = 0; |
588 | 612 | ||
589 | if (oh->slaves_cnt == 0) | 613 | while (i < oh->slaves_cnt) { |
590 | return 0; | 614 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); |
591 | |||
592 | for (i = 0; i < oh->slaves_cnt; i++) { | ||
593 | struct omap_hwmod_ocp_if *os = oh->slaves[i]; | ||
594 | |||
595 | if (!os->clk) | 615 | if (!os->clk) |
596 | continue; | 616 | continue; |
597 | 617 | ||
@@ -643,21 +663,19 @@ static int _init_opt_clks(struct omap_hwmod *oh) | |||
643 | */ | 663 | */ |
644 | static int _enable_clocks(struct omap_hwmod *oh) | 664 | static int _enable_clocks(struct omap_hwmod *oh) |
645 | { | 665 | { |
646 | int i; | 666 | struct omap_hwmod_ocp_if *os; |
667 | int i = 0; | ||
647 | 668 | ||
648 | pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); | 669 | pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); |
649 | 670 | ||
650 | if (oh->_clk) | 671 | if (oh->_clk) |
651 | clk_enable(oh->_clk); | 672 | clk_enable(oh->_clk); |
652 | 673 | ||
653 | if (oh->slaves_cnt > 0) { | 674 | while (i < oh->slaves_cnt) { |
654 | for (i = 0; i < oh->slaves_cnt; i++) { | 675 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); |
655 | struct omap_hwmod_ocp_if *os = oh->slaves[i]; | ||
656 | struct clk *c = os->_clk; | ||
657 | 676 | ||
658 | if (c && (os->flags & OCPIF_SWSUP_IDLE)) | 677 | if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) |
659 | clk_enable(c); | 678 | clk_enable(os->_clk); |
660 | } | ||
661 | } | 679 | } |
662 | 680 | ||
663 | /* The opt clocks are controlled by the device driver. */ | 681 | /* The opt clocks are controlled by the device driver. */ |
@@ -673,21 +691,19 @@ static int _enable_clocks(struct omap_hwmod *oh) | |||
673 | */ | 691 | */ |
674 | static int _disable_clocks(struct omap_hwmod *oh) | 692 | static int _disable_clocks(struct omap_hwmod *oh) |
675 | { | 693 | { |
676 | int i; | 694 | struct omap_hwmod_ocp_if *os; |
695 | int i = 0; | ||
677 | 696 | ||
678 | pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); | 697 | pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); |
679 | 698 | ||
680 | if (oh->_clk) | 699 | if (oh->_clk) |
681 | clk_disable(oh->_clk); | 700 | clk_disable(oh->_clk); |
682 | 701 | ||
683 | if (oh->slaves_cnt > 0) { | 702 | while (i < oh->slaves_cnt) { |
684 | for (i = 0; i < oh->slaves_cnt; i++) { | 703 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); |
685 | struct omap_hwmod_ocp_if *os = oh->slaves[i]; | ||
686 | struct clk *c = os->_clk; | ||
687 | 704 | ||
688 | if (c && (os->flags & OCPIF_SWSUP_IDLE)) | 705 | if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) |
689 | clk_disable(c); | 706 | clk_disable(os->_clk); |
690 | } | ||
691 | } | 707 | } |
692 | 708 | ||
693 | /* The opt clocks are controlled by the device driver. */ | 709 | /* The opt clocks are controlled by the device driver. */ |
@@ -961,8 +977,9 @@ static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, | |||
961 | struct omap_hwmod_ocp_if *os; | 977 | struct omap_hwmod_ocp_if *os; |
962 | bool found = false; | 978 | bool found = false; |
963 | 979 | ||
964 | for (i = 0; i < oh->slaves_cnt; i++) { | 980 | i = 0; |
965 | os = oh->slaves[i]; | 981 | while (i < oh->slaves_cnt) { |
982 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); | ||
966 | 983 | ||
967 | if (!os->addr) | 984 | if (!os->addr) |
968 | return -ENOENT; | 985 | return -ENOENT; |
@@ -999,15 +1016,15 @@ static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, | |||
999 | */ | 1016 | */ |
1000 | static int __init _find_mpu_port_index(struct omap_hwmod *oh) | 1017 | static int __init _find_mpu_port_index(struct omap_hwmod *oh) |
1001 | { | 1018 | { |
1002 | int i; | 1019 | struct omap_hwmod_ocp_if *os; |
1020 | int i = 0; | ||
1003 | int found = 0; | 1021 | int found = 0; |
1004 | 1022 | ||
1005 | if (!oh || oh->slaves_cnt == 0) | 1023 | if (!oh) |
1006 | return -EINVAL; | 1024 | return -EINVAL; |
1007 | 1025 | ||
1008 | for (i = 0; i < oh->slaves_cnt; i++) { | 1026 | while (i < oh->slaves_cnt) { |
1009 | struct omap_hwmod_ocp_if *os = oh->slaves[i]; | 1027 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); |
1010 | |||
1011 | if (os->user & OCP_USER_MPU) { | 1028 | if (os->user & OCP_USER_MPU) { |
1012 | found = 1; | 1029 | found = 1; |
1013 | break; | 1030 | break; |
@@ -1016,12 +1033,12 @@ static int __init _find_mpu_port_index(struct omap_hwmod *oh) | |||
1016 | 1033 | ||
1017 | if (found) | 1034 | if (found) |
1018 | pr_debug("omap_hwmod: %s: MPU OCP slave port ID %d\n", | 1035 | pr_debug("omap_hwmod: %s: MPU OCP slave port ID %d\n", |
1019 | oh->name, i); | 1036 | oh->name, i - 1); |
1020 | else | 1037 | else |
1021 | pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n", | 1038 | pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n", |
1022 | oh->name); | 1039 | oh->name); |
1023 | 1040 | ||
1024 | return (found) ? i : -EINVAL; | 1041 | return (found) ? (i - 1) : -EINVAL; |
1025 | } | 1042 | } |
1026 | 1043 | ||
1027 | /** | 1044 | /** |
@@ -2027,23 +2044,22 @@ static int __init _init(struct omap_hwmod *oh, void *data) | |||
2027 | */ | 2044 | */ |
2028 | static void __init _setup_iclk_autoidle(struct omap_hwmod *oh) | 2045 | static void __init _setup_iclk_autoidle(struct omap_hwmod *oh) |
2029 | { | 2046 | { |
2030 | int i; | 2047 | struct omap_hwmod_ocp_if *os; |
2031 | 2048 | int i = 0; | |
2032 | if (oh->_state != _HWMOD_STATE_INITIALIZED) | 2049 | if (oh->_state != _HWMOD_STATE_INITIALIZED) |
2033 | return; | 2050 | return; |
2034 | 2051 | ||
2035 | for (i = 0; i < oh->slaves_cnt; i++) { | ||
2036 | struct omap_hwmod_ocp_if *os = oh->slaves[i]; | ||
2037 | struct clk *c = os->_clk; | ||
2038 | 2052 | ||
2039 | if (!c) | 2053 | while (i < oh->slaves_cnt) { |
2054 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); | ||
2055 | if (!os->_clk) | ||
2040 | continue; | 2056 | continue; |
2041 | 2057 | ||
2042 | if (os->flags & OCPIF_SWSUP_IDLE) { | 2058 | if (os->flags & OCPIF_SWSUP_IDLE) { |
2043 | /* XXX omap_iclk_deny_idle(c); */ | 2059 | /* XXX omap_iclk_deny_idle(c); */ |
2044 | } else { | 2060 | } else { |
2045 | /* XXX omap_iclk_allow_idle(c); */ | 2061 | /* XXX omap_iclk_allow_idle(c); */ |
2046 | clk_enable(c); | 2062 | clk_enable(os->_clk); |
2047 | } | 2063 | } |
2048 | } | 2064 | } |
2049 | 2065 | ||
@@ -2623,12 +2639,16 @@ int omap_hwmod_reset(struct omap_hwmod *oh) | |||
2623 | */ | 2639 | */ |
2624 | int omap_hwmod_count_resources(struct omap_hwmod *oh) | 2640 | int omap_hwmod_count_resources(struct omap_hwmod *oh) |
2625 | { | 2641 | { |
2626 | int ret, i; | 2642 | struct omap_hwmod_ocp_if *os; |
2643 | int ret; | ||
2644 | int i = 0; | ||
2627 | 2645 | ||
2628 | ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh); | 2646 | ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh); |
2629 | 2647 | ||
2630 | for (i = 0; i < oh->slaves_cnt; i++) | 2648 | while (i < oh->slaves_cnt) { |
2631 | ret += _count_ocp_if_addr_spaces(oh->slaves[i]); | 2649 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); |
2650 | ret += _count_ocp_if_addr_spaces(os); | ||
2651 | } | ||
2632 | 2652 | ||
2633 | return ret; | 2653 | return ret; |
2634 | } | 2654 | } |
@@ -2645,7 +2665,8 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh) | |||
2645 | */ | 2665 | */ |
2646 | int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) | 2666 | int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) |
2647 | { | 2667 | { |
2648 | int i, j, mpu_irqs_cnt, sdma_reqs_cnt; | 2668 | struct omap_hwmod_ocp_if *os; |
2669 | int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt; | ||
2649 | int r = 0; | 2670 | int r = 0; |
2650 | 2671 | ||
2651 | /* For each IRQ, DMA, memory area, fill in array.*/ | 2672 | /* For each IRQ, DMA, memory area, fill in array.*/ |
@@ -2668,11 +2689,9 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) | |||
2668 | r++; | 2689 | r++; |
2669 | } | 2690 | } |
2670 | 2691 | ||
2671 | for (i = 0; i < oh->slaves_cnt; i++) { | 2692 | i = 0; |
2672 | struct omap_hwmod_ocp_if *os; | 2693 | while (i < oh->slaves_cnt) { |
2673 | int addr_cnt; | 2694 | os = _fetch_next_ocp_if(NULL, oh->slaves, &i); |
2674 | |||
2675 | os = oh->slaves[i]; | ||
2676 | addr_cnt = _count_ocp_if_addr_spaces(os); | 2695 | addr_cnt = _count_ocp_if_addr_spaces(os); |
2677 | 2696 | ||
2678 | for (j = 0; j < addr_cnt; j++) { | 2697 | for (j = 0; j < addr_cnt; j++) { |