diff options
51 files changed, 1138 insertions, 1331 deletions
diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 704be9306c9f..01683707060b 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt | |||
@@ -46,6 +46,9 @@ Timing properties for child nodes. All are optional and default to 0. | |||
46 | - gpmc,adv-on-ns: Assertion time | 46 | - gpmc,adv-on-ns: Assertion time |
47 | - gpmc,adv-rd-off-ns: Read deassertion time | 47 | - gpmc,adv-rd-off-ns: Read deassertion time |
48 | - gpmc,adv-wr-off-ns: Write deassertion time | 48 | - gpmc,adv-wr-off-ns: Write deassertion time |
49 | - gpmc,adv-aad-mux-on-ns: Assertion time for AAD | ||
50 | - gpmc,adv-aad-mux-rd-off-ns: Read deassertion time for AAD | ||
51 | - gpmc,adv-aad-mux-wr-off-ns: Write deassertion time for AAD | ||
49 | 52 | ||
50 | WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: | 53 | WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: |
51 | - gpmc,we-on-ns Assertion time | 54 | - gpmc,we-on-ns Assertion time |
@@ -54,6 +57,8 @@ Timing properties for child nodes. All are optional and default to 0. | |||
54 | OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: | 57 | OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: |
55 | - gpmc,oe-on-ns: Assertion time | 58 | - gpmc,oe-on-ns: Assertion time |
56 | - gpmc,oe-off-ns: Deassertion time | 59 | - gpmc,oe-off-ns: Deassertion time |
60 | - gpmc,oe-aad-mux-on-ns: Assertion time for AAD | ||
61 | - gpmc,oe-aad-mux-off-ns: Deassertion time for AAD | ||
57 | 62 | ||
58 | Access time and cycle time timings (in nanoseconds) corresponding to | 63 | Access time and cycle time timings (in nanoseconds) corresponding to |
59 | GPMC_CONFIG5: | 64 | GPMC_CONFIG5: |
diff --git a/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt b/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt new file mode 100644 index 000000000000..8c05d16367df --- /dev/null +++ b/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt | |||
@@ -0,0 +1,55 @@ | |||
1 | Pistachio Reset Controller | ||
2 | ============================================================================= | ||
3 | |||
4 | This binding describes a reset controller device that is used to enable and | ||
5 | disable individual IP blocks within the Pistachio SoC using "soft reset" | ||
6 | control bits found in the Pistachio SoC top level registers. | ||
7 | |||
8 | The actual action taken when soft reset is asserted is hardware dependent. | ||
9 | However, when asserted it may not be possible to access the hardware's | ||
10 | registers, and following an assert/deassert sequence the hardware's previous | ||
11 | state may no longer be valid. | ||
12 | |||
13 | Please refer to Documentation/devicetree/bindings/reset/reset.txt | ||
14 | for common reset controller binding usage. | ||
15 | |||
16 | Required properties: | ||
17 | |||
18 | - compatible: Contains "img,pistachio-reset" | ||
19 | |||
20 | - #reset-cells: Contains 1 | ||
21 | |||
22 | Example: | ||
23 | |||
24 | cr_periph: clk@18148000 { | ||
25 | compatible = "img,pistachio-cr-periph", "syscon", "simple-mfd"; | ||
26 | reg = <0x18148000 0x1000>; | ||
27 | clocks = <&clk_periph PERIPH_CLK_SYS>; | ||
28 | clock-names = "sys"; | ||
29 | #clock-cells = <1>; | ||
30 | |||
31 | pistachio_reset: reset-controller { | ||
32 | compatible = "img,pistachio-reset"; | ||
33 | #reset-cells = <1>; | ||
34 | }; | ||
35 | }; | ||
36 | |||
37 | Specifying reset control of devices | ||
38 | ======================================= | ||
39 | |||
40 | Device nodes should specify the reset channel required in their "resets" | ||
41 | property, containing a phandle to the pistachio reset device node and an | ||
42 | index specifying which reset to use, as described in | ||
43 | Documentation/devicetree/bindings/reset/reset.txt. | ||
44 | |||
45 | Example: | ||
46 | |||
47 | spdif_out: spdif-out@18100d00 { | ||
48 | ... | ||
49 | resets = <&pistachio_reset PISTACHIO_RESET_SPDIF_OUT>; | ||
50 | reset-names = "rst"; | ||
51 | ... | ||
52 | }; | ||
53 | |||
54 | Macro definitions for the supported resets can be found in: | ||
55 | include/dt-bindings/reset/pistachio-resets.h | ||
diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt index 112756e11802..13dc6a3fdb4a 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt | |||
@@ -6,6 +6,7 @@ powered up/down by software based on different application scenes to save power. | |||
6 | Required properties for power domain controller: | 6 | Required properties for power domain controller: |
7 | - compatible: Should be one of the following. | 7 | - compatible: Should be one of the following. |
8 | "rockchip,rk3288-power-controller" - for RK3288 SoCs. | 8 | "rockchip,rk3288-power-controller" - for RK3288 SoCs. |
9 | "rockchip,rk3368-power-controller" - for RK3368 SoCs. | ||
9 | - #power-domain-cells: Number of cells in a power-domain specifier. | 10 | - #power-domain-cells: Number of cells in a power-domain specifier. |
10 | Should be 1 for multiple PM domains. | 11 | Should be 1 for multiple PM domains. |
11 | - #address-cells: Should be 1. | 12 | - #address-cells: Should be 1. |
@@ -14,6 +15,7 @@ Required properties for power domain controller: | |||
14 | Required properties for power domain sub nodes: | 15 | Required properties for power domain sub nodes: |
15 | - reg: index of the power domain, should use macros in: | 16 | - reg: index of the power domain, should use macros in: |
16 | "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain. | 17 | "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain. |
18 | "include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain. | ||
17 | - clocks (optional): phandles to clocks which need to be enabled while power domain | 19 | - clocks (optional): phandles to clocks which need to be enabled while power domain |
18 | switches state. | 20 | switches state. |
19 | 21 | ||
@@ -31,11 +33,24 @@ Example: | |||
31 | }; | 33 | }; |
32 | }; | 34 | }; |
33 | 35 | ||
36 | power: power-controller { | ||
37 | compatible = "rockchip,rk3368-power-controller"; | ||
38 | #power-domain-cells = <1>; | ||
39 | #address-cells = <1>; | ||
40 | #size-cells = <0>; | ||
41 | |||
42 | pd_gpu_1 { | ||
43 | reg = <RK3368_PD_GPU_1>; | ||
44 | clocks = <&cru ACLK_GPU_CFG>; | ||
45 | }; | ||
46 | }; | ||
47 | |||
34 | Node of a device using power domains must have a power-domains property, | 48 | Node of a device using power domains must have a power-domains property, |
35 | containing a phandle to the power device node and an index specifying which | 49 | containing a phandle to the power device node and an index specifying which |
36 | power domain to use. | 50 | power domain to use. |
37 | The index should use macros in: | 51 | The index should use macros in: |
38 | "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain. | 52 | "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain. |
53 | "include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain. | ||
39 | 54 | ||
40 | Example of the node using power domain: | 55 | Example of the node using power domain: |
41 | 56 | ||
@@ -44,3 +59,9 @@ Example of the node using power domain: | |||
44 | power-domains = <&power RK3288_PD_GPU>; | 59 | power-domains = <&power RK3288_PD_GPU>; |
45 | /* ... */ | 60 | /* ... */ |
46 | }; | 61 | }; |
62 | |||
63 | node { | ||
64 | /* ... */ | ||
65 | power-domains = <&power RK3368_PD_GPU_1>; | ||
66 | /* ... */ | ||
67 | }; | ||
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 23be2e433097..08047afdf38e 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -104,6 +104,7 @@ config HAVE_AT91_USB_CLK | |||
104 | config COMMON_CLK_AT91 | 104 | config COMMON_CLK_AT91 |
105 | bool | 105 | bool |
106 | select COMMON_CLK | 106 | select COMMON_CLK |
107 | select MFD_SYSCON | ||
107 | 108 | ||
108 | config HAVE_AT91_SMD | 109 | config HAVE_AT91_SMD |
109 | bool | 110 | bool |
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index c1a7c6cc00e1..63b4fa25b48a 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/of_platform.h> | 12 | #include <linux/of_platform.h> |
13 | 13 | ||
14 | #include <asm/mach/arch.h> | 14 | #include <asm/mach/arch.h> |
15 | #include <asm/system_misc.h> | ||
16 | 15 | ||
17 | #include "generic.h" | 16 | #include "generic.h" |
18 | #include "soc.h" | 17 | #include "soc.h" |
@@ -33,7 +32,6 @@ static void __init at91rm9200_dt_device_init(void) | |||
33 | 32 | ||
34 | of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); | 33 | of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); |
35 | 34 | ||
36 | arm_pm_idle = at91rm9200_idle; | ||
37 | at91rm9200_pm_init(); | 35 | at91rm9200_pm_init(); |
38 | } | 36 | } |
39 | 37 | ||
diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c index 7eb64f763034..cada2a6412b3 100644 --- a/arch/arm/mach-at91/at91sam9.c +++ b/arch/arm/mach-at91/at91sam9.c | |||
@@ -62,8 +62,6 @@ static void __init at91sam9_common_init(void) | |||
62 | soc_dev = soc_device_to_device(soc); | 62 | soc_dev = soc_device_to_device(soc); |
63 | 63 | ||
64 | of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); | 64 | of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); |
65 | |||
66 | arm_pm_idle = at91sam9_idle; | ||
67 | } | 65 | } |
68 | 66 | ||
69 | static void __init at91sam9_dt_device_init(void) | 67 | static void __init at91sam9_dt_device_init(void) |
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index b0fa7dc7286d..28ca57a2060f 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h | |||
@@ -11,27 +11,18 @@ | |||
11 | #ifndef _AT91_GENERIC_H | 11 | #ifndef _AT91_GENERIC_H |
12 | #define _AT91_GENERIC_H | 12 | #define _AT91_GENERIC_H |
13 | 13 | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/reboot.h> | ||
16 | |||
17 | /* Map io */ | ||
18 | extern void __init at91_map_io(void); | ||
19 | extern void __init at91_alt_map_io(void); | ||
20 | |||
21 | /* idle */ | ||
22 | extern void at91rm9200_idle(void); | ||
23 | extern void at91sam9_idle(void); | ||
24 | |||
25 | #ifdef CONFIG_PM | 14 | #ifdef CONFIG_PM |
26 | extern void __init at91rm9200_pm_init(void); | 15 | extern void __init at91rm9200_pm_init(void); |
27 | extern void __init at91sam9260_pm_init(void); | 16 | extern void __init at91sam9260_pm_init(void); |
28 | extern void __init at91sam9g45_pm_init(void); | 17 | extern void __init at91sam9g45_pm_init(void); |
29 | extern void __init at91sam9x5_pm_init(void); | 18 | extern void __init at91sam9x5_pm_init(void); |
19 | extern void __init sama5_pm_init(void); | ||
30 | #else | 20 | #else |
31 | static inline void __init at91rm9200_pm_init(void) { } | 21 | static inline void __init at91rm9200_pm_init(void) { } |
32 | static inline void __init at91sam9260_pm_init(void) { } | 22 | static inline void __init at91sam9260_pm_init(void) { } |
33 | static inline void __init at91sam9g45_pm_init(void) { } | 23 | static inline void __init at91sam9g45_pm_init(void) { } |
34 | static inline void __init at91sam9x5_pm_init(void) { } | 24 | static inline void __init at91sam9x5_pm_init(void) { } |
25 | static inline void __init sama5_pm_init(void) { } | ||
35 | #endif | 26 | #endif |
36 | 27 | ||
37 | #endif /* _AT91_GENERIC_H */ | 28 | #endif /* _AT91_GENERIC_H */ |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 23726fb31741..f06270198bf1 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -31,10 +31,13 @@ | |||
31 | #include <asm/mach/irq.h> | 31 | #include <asm/mach/irq.h> |
32 | #include <asm/fncpy.h> | 32 | #include <asm/fncpy.h> |
33 | #include <asm/cacheflush.h> | 33 | #include <asm/cacheflush.h> |
34 | #include <asm/system_misc.h> | ||
34 | 35 | ||
35 | #include "generic.h" | 36 | #include "generic.h" |
36 | #include "pm.h" | 37 | #include "pm.h" |
37 | 38 | ||
39 | static void __iomem *pmc; | ||
40 | |||
38 | /* | 41 | /* |
39 | * FIXME: this is needed to communicate between the pinctrl driver and | 42 | * FIXME: this is needed to communicate between the pinctrl driver and |
40 | * the PM implementation in the machine. Possibly part of the PM | 43 | * the PM implementation in the machine. Possibly part of the PM |
@@ -87,7 +90,7 @@ static int at91_pm_verify_clocks(void) | |||
87 | unsigned long scsr; | 90 | unsigned long scsr; |
88 | int i; | 91 | int i; |
89 | 92 | ||
90 | scsr = at91_pmc_read(AT91_PMC_SCSR); | 93 | scsr = readl(pmc + AT91_PMC_SCSR); |
91 | 94 | ||
92 | /* USB must not be using PLLB */ | 95 | /* USB must not be using PLLB */ |
93 | if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { | 96 | if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { |
@@ -101,8 +104,7 @@ static int at91_pm_verify_clocks(void) | |||
101 | 104 | ||
102 | if ((scsr & (AT91_PMC_PCK0 << i)) == 0) | 105 | if ((scsr & (AT91_PMC_PCK0 << i)) == 0) |
103 | continue; | 106 | continue; |
104 | 107 | css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS; | |
105 | css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; | ||
106 | if (css != AT91_PMC_CSS_SLOW) { | 108 | if (css != AT91_PMC_CSS_SLOW) { |
107 | pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); | 109 | pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); |
108 | return 0; | 110 | return 0; |
@@ -145,8 +147,8 @@ static void at91_pm_suspend(suspend_state_t state) | |||
145 | flush_cache_all(); | 147 | flush_cache_all(); |
146 | outer_disable(); | 148 | outer_disable(); |
147 | 149 | ||
148 | at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0], | 150 | at91_suspend_sram_fn(pmc, at91_ramc_base[0], |
149 | at91_ramc_base[1], pm_data); | 151 | at91_ramc_base[1], pm_data); |
150 | 152 | ||
151 | outer_resume(); | 153 | outer_resume(); |
152 | } | 154 | } |
@@ -353,6 +355,21 @@ static __init void at91_dt_ramc(void) | |||
353 | at91_pm_set_standby(standby); | 355 | at91_pm_set_standby(standby); |
354 | } | 356 | } |
355 | 357 | ||
358 | void at91rm9200_idle(void) | ||
359 | { | ||
360 | /* | ||
361 | * Disable the processor clock. The processor will be automatically | ||
362 | * re-enabled by an interrupt or by a reset. | ||
363 | */ | ||
364 | writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); | ||
365 | } | ||
366 | |||
367 | void at91sam9_idle(void) | ||
368 | { | ||
369 | writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); | ||
370 | cpu_do_idle(); | ||
371 | } | ||
372 | |||
356 | static void __init at91_pm_sram_init(void) | 373 | static void __init at91_pm_sram_init(void) |
357 | { | 374 | { |
358 | struct gen_pool *sram_pool; | 375 | struct gen_pool *sram_pool; |
@@ -399,13 +416,36 @@ static void __init at91_pm_sram_init(void) | |||
399 | &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); | 416 | &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); |
400 | } | 417 | } |
401 | 418 | ||
402 | static void __init at91_pm_init(void) | 419 | static const struct of_device_id atmel_pmc_ids[] __initconst = { |
420 | { .compatible = "atmel,at91rm9200-pmc" }, | ||
421 | { .compatible = "atmel,at91sam9260-pmc" }, | ||
422 | { .compatible = "atmel,at91sam9g45-pmc" }, | ||
423 | { .compatible = "atmel,at91sam9n12-pmc" }, | ||
424 | { .compatible = "atmel,at91sam9x5-pmc" }, | ||
425 | { .compatible = "atmel,sama5d3-pmc" }, | ||
426 | { .compatible = "atmel,sama5d2-pmc" }, | ||
427 | { /* sentinel */ }, | ||
428 | }; | ||
429 | |||
430 | static void __init at91_pm_init(void (*pm_idle)(void)) | ||
403 | { | 431 | { |
404 | at91_pm_sram_init(); | 432 | struct device_node *pmc_np; |
405 | 433 | ||
406 | if (at91_cpuidle_device.dev.platform_data) | 434 | if (at91_cpuidle_device.dev.platform_data) |
407 | platform_device_register(&at91_cpuidle_device); | 435 | platform_device_register(&at91_cpuidle_device); |
408 | 436 | ||
437 | pmc_np = of_find_matching_node(NULL, atmel_pmc_ids); | ||
438 | pmc = of_iomap(pmc_np, 0); | ||
439 | if (!pmc) { | ||
440 | pr_err("AT91: PM not supported, PMC not found\n"); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | if (pm_idle) | ||
445 | arm_pm_idle = pm_idle; | ||
446 | |||
447 | at91_pm_sram_init(); | ||
448 | |||
409 | if (at91_suspend_sram_fn) | 449 | if (at91_suspend_sram_fn) |
410 | suspend_set_ops(&at91_pm_ops); | 450 | suspend_set_ops(&at91_pm_ops); |
411 | else | 451 | else |
@@ -424,7 +464,7 @@ void __init at91rm9200_pm_init(void) | |||
424 | at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP; | 464 | at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP; |
425 | at91_pm_data.memctrl = AT91_MEMCTRL_MC; | 465 | at91_pm_data.memctrl = AT91_MEMCTRL_MC; |
426 | 466 | ||
427 | at91_pm_init(); | 467 | at91_pm_init(at91rm9200_idle); |
428 | } | 468 | } |
429 | 469 | ||
430 | void __init at91sam9260_pm_init(void) | 470 | void __init at91sam9260_pm_init(void) |
@@ -432,7 +472,7 @@ void __init at91sam9260_pm_init(void) | |||
432 | at91_dt_ramc(); | 472 | at91_dt_ramc(); |
433 | at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC; | 473 | at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC; |
434 | at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; | 474 | at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; |
435 | return at91_pm_init(); | 475 | at91_pm_init(at91sam9_idle); |
436 | } | 476 | } |
437 | 477 | ||
438 | void __init at91sam9g45_pm_init(void) | 478 | void __init at91sam9g45_pm_init(void) |
@@ -440,7 +480,7 @@ void __init at91sam9g45_pm_init(void) | |||
440 | at91_dt_ramc(); | 480 | at91_dt_ramc(); |
441 | at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP; | 481 | at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP; |
442 | at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; | 482 | at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; |
443 | return at91_pm_init(); | 483 | at91_pm_init(at91sam9_idle); |
444 | } | 484 | } |
445 | 485 | ||
446 | void __init at91sam9x5_pm_init(void) | 486 | void __init at91sam9x5_pm_init(void) |
@@ -448,5 +488,13 @@ void __init at91sam9x5_pm_init(void) | |||
448 | at91_dt_ramc(); | 488 | at91_dt_ramc(); |
449 | at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; | 489 | at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; |
450 | at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; | 490 | at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; |
451 | return at91_pm_init(); | 491 | at91_pm_init(at91sam9_idle); |
492 | } | ||
493 | |||
494 | void __init sama5_pm_init(void) | ||
495 | { | ||
496 | at91_dt_ramc(); | ||
497 | at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; | ||
498 | at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; | ||
499 | at91_pm_init(NULL); | ||
452 | } | 500 | } |
diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c index d9cf6799aec0..df8fdf1cf66d 100644 --- a/arch/arm/mach-at91/sama5.c +++ b/arch/arm/mach-at91/sama5.c | |||
@@ -51,7 +51,7 @@ static void __init sama5_dt_device_init(void) | |||
51 | soc_dev = soc_device_to_device(soc); | 51 | soc_dev = soc_device_to_device(soc); |
52 | 52 | ||
53 | of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); | 53 | of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); |
54 | at91sam9x5_pm_init(); | 54 | sama5_pm_init(); |
55 | } | 55 | } |
56 | 56 | ||
57 | static const char *const sama5_dt_board_compat[] __initconst = { | 57 | static const char *const sama5_dt_board_compat[] __initconst = { |
diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c index e98d15eaa799..1827fc4d15c1 100644 --- a/drivers/bus/imx-weim.c +++ b/drivers/bus/imx-weim.c | |||
@@ -150,7 +150,7 @@ static int __init weim_parse_dt(struct platform_device *pdev, | |||
150 | return ret; | 150 | return ret; |
151 | } | 151 | } |
152 | 152 | ||
153 | for_each_child_of_node(pdev->dev.of_node, child) { | 153 | for_each_available_child_of_node(pdev->dev.of_node, child) { |
154 | if (!child->name) | 154 | if (!child->name) |
155 | continue; | 155 | continue; |
156 | 156 | ||
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 25996e256110..795c9d9c96a6 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c | |||
@@ -330,7 +330,7 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, | |||
330 | cmd = RSB_CMD_RD32; | 330 | cmd = RSB_CMD_RD32; |
331 | break; | 331 | break; |
332 | default: | 332 | default: |
333 | dev_err(rsb->dev, "Invalid access width: %d\n", len); | 333 | dev_err(rsb->dev, "Invalid access width: %zd\n", len); |
334 | return -EINVAL; | 334 | return -EINVAL; |
335 | } | 335 | } |
336 | 336 | ||
@@ -372,7 +372,7 @@ static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, | |||
372 | cmd = RSB_CMD_WR32; | 372 | cmd = RSB_CMD_WR32; |
373 | break; | 373 | break; |
374 | default: | 374 | default: |
375 | dev_err(rsb->dev, "Invalid access width: %d\n", len); | 375 | dev_err(rsb->dev, "Invalid access width: %zd\n", len); |
376 | return -EINVAL; | 376 | return -EINVAL; |
377 | } | 377 | } |
378 | 378 | ||
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index abc80949e1dd..4ad3298eb372 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c | |||
@@ -15,8 +15,8 @@ | |||
15 | #include <linux/clkdev.h> | 15 | #include <linux/clkdev.h> |
16 | #include <linux/clk/at91_pmc.h> | 16 | #include <linux/clk/at91_pmc.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/mfd/syscon.h> |
19 | #include <linux/io.h> | 19 | #include <linux/regmap.h> |
20 | 20 | ||
21 | #include "pmc.h" | 21 | #include "pmc.h" |
22 | 22 | ||
@@ -28,8 +28,9 @@ | |||
28 | 28 | ||
29 | struct clk_generated { | 29 | struct clk_generated { |
30 | struct clk_hw hw; | 30 | struct clk_hw hw; |
31 | struct at91_pmc *pmc; | 31 | struct regmap *regmap; |
32 | struct clk_range range; | 32 | struct clk_range range; |
33 | spinlock_t *lock; | ||
33 | u32 id; | 34 | u32 id; |
34 | u32 gckdiv; | 35 | u32 gckdiv; |
35 | u8 parent_id; | 36 | u8 parent_id; |
@@ -41,49 +42,52 @@ struct clk_generated { | |||
41 | static int clk_generated_enable(struct clk_hw *hw) | 42 | static int clk_generated_enable(struct clk_hw *hw) |
42 | { | 43 | { |
43 | struct clk_generated *gck = to_clk_generated(hw); | 44 | struct clk_generated *gck = to_clk_generated(hw); |
44 | struct at91_pmc *pmc = gck->pmc; | 45 | unsigned long flags; |
45 | u32 tmp; | ||
46 | 46 | ||
47 | pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", | 47 | pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", |
48 | __func__, gck->gckdiv, gck->parent_id); | 48 | __func__, gck->gckdiv, gck->parent_id); |
49 | 49 | ||
50 | pmc_lock(pmc); | 50 | spin_lock_irqsave(gck->lock, flags); |
51 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | 51 | regmap_write(gck->regmap, AT91_PMC_PCR, |
52 | tmp = pmc_read(pmc, AT91_PMC_PCR) & | 52 | (gck->id & AT91_PMC_PCR_PID_MASK)); |
53 | ~(AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK); | 53 | regmap_update_bits(gck->regmap, AT91_PMC_PCR, |
54 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_GCKCSS(gck->parent_id) | 54 | AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK | |
55 | | AT91_PMC_PCR_CMD | 55 | AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, |
56 | | AT91_PMC_PCR_GCKDIV(gck->gckdiv) | 56 | AT91_PMC_PCR_GCKCSS(gck->parent_id) | |
57 | | AT91_PMC_PCR_GCKEN); | 57 | AT91_PMC_PCR_CMD | |
58 | pmc_unlock(pmc); | 58 | AT91_PMC_PCR_GCKDIV(gck->gckdiv) | |
59 | AT91_PMC_PCR_GCKEN); | ||
60 | spin_unlock_irqrestore(gck->lock, flags); | ||
59 | return 0; | 61 | return 0; |
60 | } | 62 | } |
61 | 63 | ||
62 | static void clk_generated_disable(struct clk_hw *hw) | 64 | static void clk_generated_disable(struct clk_hw *hw) |
63 | { | 65 | { |
64 | struct clk_generated *gck = to_clk_generated(hw); | 66 | struct clk_generated *gck = to_clk_generated(hw); |
65 | struct at91_pmc *pmc = gck->pmc; | 67 | unsigned long flags; |
66 | u32 tmp; | 68 | |
67 | 69 | spin_lock_irqsave(gck->lock, flags); | |
68 | pmc_lock(pmc); | 70 | regmap_write(gck->regmap, AT91_PMC_PCR, |
69 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | 71 | (gck->id & AT91_PMC_PCR_PID_MASK)); |
70 | tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_GCKEN; | 72 | regmap_update_bits(gck->regmap, AT91_PMC_PCR, |
71 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD); | 73 | AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, |
72 | pmc_unlock(pmc); | 74 | AT91_PMC_PCR_CMD); |
75 | spin_unlock_irqrestore(gck->lock, flags); | ||
73 | } | 76 | } |
74 | 77 | ||
75 | static int clk_generated_is_enabled(struct clk_hw *hw) | 78 | static int clk_generated_is_enabled(struct clk_hw *hw) |
76 | { | 79 | { |
77 | struct clk_generated *gck = to_clk_generated(hw); | 80 | struct clk_generated *gck = to_clk_generated(hw); |
78 | struct at91_pmc *pmc = gck->pmc; | 81 | unsigned long flags; |
79 | int ret; | 82 | unsigned int status; |
80 | 83 | ||
81 | pmc_lock(pmc); | 84 | spin_lock_irqsave(gck->lock, flags); |
82 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | 85 | regmap_write(gck->regmap, AT91_PMC_PCR, |
83 | ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_GCKEN); | 86 | (gck->id & AT91_PMC_PCR_PID_MASK)); |
84 | pmc_unlock(pmc); | 87 | regmap_read(gck->regmap, AT91_PMC_PCR, &status); |
88 | spin_unlock_irqrestore(gck->lock, flags); | ||
85 | 89 | ||
86 | return ret; | 90 | return status & AT91_PMC_PCR_GCKEN ? 1 : 0; |
87 | } | 91 | } |
88 | 92 | ||
89 | static unsigned long | 93 | static unsigned long |
@@ -214,13 +218,14 @@ static const struct clk_ops generated_ops = { | |||
214 | */ | 218 | */ |
215 | static void clk_generated_startup(struct clk_generated *gck) | 219 | static void clk_generated_startup(struct clk_generated *gck) |
216 | { | 220 | { |
217 | struct at91_pmc *pmc = gck->pmc; | ||
218 | u32 tmp; | 221 | u32 tmp; |
222 | unsigned long flags; | ||
219 | 223 | ||
220 | pmc_lock(pmc); | 224 | spin_lock_irqsave(gck->lock, flags); |
221 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | 225 | regmap_write(gck->regmap, AT91_PMC_PCR, |
222 | tmp = pmc_read(pmc, AT91_PMC_PCR); | 226 | (gck->id & AT91_PMC_PCR_PID_MASK)); |
223 | pmc_unlock(pmc); | 227 | regmap_read(gck->regmap, AT91_PMC_PCR, &tmp); |
228 | spin_unlock_irqrestore(gck->lock, flags); | ||
224 | 229 | ||
225 | gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK) | 230 | gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK) |
226 | >> AT91_PMC_PCR_GCKCSS_OFFSET; | 231 | >> AT91_PMC_PCR_GCKCSS_OFFSET; |
@@ -229,8 +234,8 @@ static void clk_generated_startup(struct clk_generated *gck) | |||
229 | } | 234 | } |
230 | 235 | ||
231 | static struct clk * __init | 236 | static struct clk * __init |
232 | at91_clk_register_generated(struct at91_pmc *pmc, const char *name, | 237 | at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char |
233 | const char **parent_names, u8 num_parents, | 238 | *name, const char **parent_names, u8 num_parents, |
234 | u8 id, const struct clk_range *range) | 239 | u8 id, const struct clk_range *range) |
235 | { | 240 | { |
236 | struct clk_generated *gck; | 241 | struct clk_generated *gck; |
@@ -249,7 +254,8 @@ at91_clk_register_generated(struct at91_pmc *pmc, const char *name, | |||
249 | 254 | ||
250 | gck->id = id; | 255 | gck->id = id; |
251 | gck->hw.init = &init; | 256 | gck->hw.init = &init; |
252 | gck->pmc = pmc; | 257 | gck->regmap = regmap; |
258 | gck->lock = lock; | ||
253 | gck->range = *range; | 259 | gck->range = *range; |
254 | 260 | ||
255 | clk = clk_register(NULL, &gck->hw); | 261 | clk = clk_register(NULL, &gck->hw); |
@@ -261,8 +267,7 @@ at91_clk_register_generated(struct at91_pmc *pmc, const char *name, | |||
261 | return clk; | 267 | return clk; |
262 | } | 268 | } |
263 | 269 | ||
264 | void __init of_sama5d2_clk_generated_setup(struct device_node *np, | 270 | void __init of_sama5d2_clk_generated_setup(struct device_node *np) |
265 | struct at91_pmc *pmc) | ||
266 | { | 271 | { |
267 | int num; | 272 | int num; |
268 | u32 id; | 273 | u32 id; |
@@ -272,6 +277,7 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np, | |||
272 | const char *parent_names[GENERATED_SOURCE_MAX]; | 277 | const char *parent_names[GENERATED_SOURCE_MAX]; |
273 | struct device_node *gcknp; | 278 | struct device_node *gcknp; |
274 | struct clk_range range = CLK_RANGE(0, 0); | 279 | struct clk_range range = CLK_RANGE(0, 0); |
280 | struct regmap *regmap; | ||
275 | 281 | ||
276 | num_parents = of_clk_get_parent_count(np); | 282 | num_parents = of_clk_get_parent_count(np); |
277 | if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX) | 283 | if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX) |
@@ -283,6 +289,10 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np, | |||
283 | if (!num || num > PERIPHERAL_MAX) | 289 | if (!num || num > PERIPHERAL_MAX) |
284 | return; | 290 | return; |
285 | 291 | ||
292 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
293 | if (IS_ERR(regmap)) | ||
294 | return; | ||
295 | |||
286 | for_each_child_of_node(np, gcknp) { | 296 | for_each_child_of_node(np, gcknp) { |
287 | if (of_property_read_u32(gcknp, "reg", &id)) | 297 | if (of_property_read_u32(gcknp, "reg", &id)) |
288 | continue; | 298 | continue; |
@@ -296,11 +306,14 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np, | |||
296 | of_at91_get_clk_range(gcknp, "atmel,clk-output-range", | 306 | of_at91_get_clk_range(gcknp, "atmel,clk-output-range", |
297 | &range); | 307 | &range); |
298 | 308 | ||
299 | clk = at91_clk_register_generated(pmc, name, parent_names, | 309 | clk = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, |
300 | num_parents, id, &range); | 310 | parent_names, num_parents, |
311 | id, &range); | ||
301 | if (IS_ERR(clk)) | 312 | if (IS_ERR(clk)) |
302 | continue; | 313 | continue; |
303 | 314 | ||
304 | of_clk_add_provider(gcknp, of_clk_src_simple_get, clk); | 315 | of_clk_add_provider(gcknp, of_clk_src_simple_get, clk); |
305 | } | 316 | } |
306 | } | 317 | } |
318 | CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated", | ||
319 | of_sama5d2_clk_generated_setup); | ||
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c index 61566bcefa53..819f5842fa66 100644 --- a/drivers/clk/at91/clk-h32mx.c +++ b/drivers/clk/at91/clk-h32mx.c | |||
@@ -15,15 +15,9 @@ | |||
15 | #include <linux/clk-provider.h> | 15 | #include <linux/clk-provider.h> |
16 | #include <linux/clkdev.h> | 16 | #include <linux/clkdev.h> |
17 | #include <linux/clk/at91_pmc.h> | 17 | #include <linux/clk/at91_pmc.h> |
18 | #include <linux/delay.h> | ||
19 | #include <linux/of.h> | 18 | #include <linux/of.h> |
20 | #include <linux/of_address.h> | 19 | #include <linux/regmap.h> |
21 | #include <linux/of_irq.h> | 20 | #include <linux/mfd/syscon.h> |
22 | #include <linux/io.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/wait.h> | ||
27 | 21 | ||
28 | #include "pmc.h" | 22 | #include "pmc.h" |
29 | 23 | ||
@@ -31,7 +25,7 @@ | |||
31 | 25 | ||
32 | struct clk_sama5d4_h32mx { | 26 | struct clk_sama5d4_h32mx { |
33 | struct clk_hw hw; | 27 | struct clk_hw hw; |
34 | struct at91_pmc *pmc; | 28 | struct regmap *regmap; |
35 | }; | 29 | }; |
36 | 30 | ||
37 | #define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw) | 31 | #define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw) |
@@ -40,8 +34,10 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw, | |||
40 | unsigned long parent_rate) | 34 | unsigned long parent_rate) |
41 | { | 35 | { |
42 | struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw); | 36 | struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw); |
37 | unsigned int mckr; | ||
43 | 38 | ||
44 | if (pmc_read(h32mxclk->pmc, AT91_PMC_MCKR) & AT91_PMC_H32MXDIV) | 39 | regmap_read(h32mxclk->regmap, AT91_PMC_MCKR, &mckr); |
40 | if (mckr & AT91_PMC_H32MXDIV) | ||
45 | return parent_rate / 2; | 41 | return parent_rate / 2; |
46 | 42 | ||
47 | if (parent_rate > H32MX_MAX_FREQ) | 43 | if (parent_rate > H32MX_MAX_FREQ) |
@@ -70,18 +66,16 @@ static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate, | |||
70 | unsigned long parent_rate) | 66 | unsigned long parent_rate) |
71 | { | 67 | { |
72 | struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw); | 68 | struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw); |
73 | struct at91_pmc *pmc = h32mxclk->pmc; | 69 | u32 mckr = 0; |
74 | u32 tmp; | ||
75 | 70 | ||
76 | if (parent_rate != rate && (parent_rate / 2) != rate) | 71 | if (parent_rate != rate && (parent_rate / 2) != rate) |
77 | return -EINVAL; | 72 | return -EINVAL; |
78 | 73 | ||
79 | pmc_lock(pmc); | ||
80 | tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_H32MXDIV; | ||
81 | if ((parent_rate / 2) == rate) | 74 | if ((parent_rate / 2) == rate) |
82 | tmp |= AT91_PMC_H32MXDIV; | 75 | mckr = AT91_PMC_H32MXDIV; |
83 | pmc_write(pmc, AT91_PMC_MCKR, tmp); | 76 | |
84 | pmc_unlock(pmc); | 77 | regmap_update_bits(h32mxclk->regmap, AT91_PMC_MCKR, |
78 | AT91_PMC_H32MXDIV, mckr); | ||
85 | 79 | ||
86 | return 0; | 80 | return 0; |
87 | } | 81 | } |
@@ -92,14 +86,18 @@ static const struct clk_ops h32mx_ops = { | |||
92 | .set_rate = clk_sama5d4_h32mx_set_rate, | 86 | .set_rate = clk_sama5d4_h32mx_set_rate, |
93 | }; | 87 | }; |
94 | 88 | ||
95 | void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, | 89 | static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np) |
96 | struct at91_pmc *pmc) | ||
97 | { | 90 | { |
98 | struct clk_sama5d4_h32mx *h32mxclk; | 91 | struct clk_sama5d4_h32mx *h32mxclk; |
99 | struct clk_init_data init; | 92 | struct clk_init_data init; |
100 | const char *parent_name; | 93 | const char *parent_name; |
94 | struct regmap *regmap; | ||
101 | struct clk *clk; | 95 | struct clk *clk; |
102 | 96 | ||
97 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
98 | if (IS_ERR(regmap)) | ||
99 | return; | ||
100 | |||
103 | h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL); | 101 | h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL); |
104 | if (!h32mxclk) | 102 | if (!h32mxclk) |
105 | return; | 103 | return; |
@@ -113,7 +111,7 @@ void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, | |||
113 | init.flags = CLK_SET_RATE_GATE; | 111 | init.flags = CLK_SET_RATE_GATE; |
114 | 112 | ||
115 | h32mxclk->hw.init = &init; | 113 | h32mxclk->hw.init = &init; |
116 | h32mxclk->pmc = pmc; | 114 | h32mxclk->regmap = regmap; |
117 | 115 | ||
118 | clk = clk_register(NULL, &h32mxclk->hw); | 116 | clk = clk_register(NULL, &h32mxclk->hw); |
119 | if (!clk) { | 117 | if (!clk) { |
@@ -123,3 +121,5 @@ void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, | |||
123 | 121 | ||
124 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 122 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
125 | } | 123 | } |
124 | CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx", | ||
125 | of_sama5d4_clk_h32mx_setup); | ||
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index fd7247deabdc..4bfc94d6c26e 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c | |||
@@ -13,13 +13,8 @@ | |||
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/of_address.h> | 16 | #include <linux/mfd/syscon.h> |
17 | #include <linux/of_irq.h> | 17 | #include <linux/regmap.h> |
18 | #include <linux/io.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/wait.h> | ||
23 | 18 | ||
24 | #include "pmc.h" | 19 | #include "pmc.h" |
25 | 20 | ||
@@ -34,18 +29,14 @@ | |||
34 | 29 | ||
35 | struct clk_main_osc { | 30 | struct clk_main_osc { |
36 | struct clk_hw hw; | 31 | struct clk_hw hw; |
37 | struct at91_pmc *pmc; | 32 | struct regmap *regmap; |
38 | unsigned int irq; | ||
39 | wait_queue_head_t wait; | ||
40 | }; | 33 | }; |
41 | 34 | ||
42 | #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw) | 35 | #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw) |
43 | 36 | ||
44 | struct clk_main_rc_osc { | 37 | struct clk_main_rc_osc { |
45 | struct clk_hw hw; | 38 | struct clk_hw hw; |
46 | struct at91_pmc *pmc; | 39 | struct regmap *regmap; |
47 | unsigned int irq; | ||
48 | wait_queue_head_t wait; | ||
49 | unsigned long frequency; | 40 | unsigned long frequency; |
50 | unsigned long accuracy; | 41 | unsigned long accuracy; |
51 | }; | 42 | }; |
@@ -54,51 +45,47 @@ struct clk_main_rc_osc { | |||
54 | 45 | ||
55 | struct clk_rm9200_main { | 46 | struct clk_rm9200_main { |
56 | struct clk_hw hw; | 47 | struct clk_hw hw; |
57 | struct at91_pmc *pmc; | 48 | struct regmap *regmap; |
58 | }; | 49 | }; |
59 | 50 | ||
60 | #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw) | 51 | #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw) |
61 | 52 | ||
62 | struct clk_sam9x5_main { | 53 | struct clk_sam9x5_main { |
63 | struct clk_hw hw; | 54 | struct clk_hw hw; |
64 | struct at91_pmc *pmc; | 55 | struct regmap *regmap; |
65 | unsigned int irq; | ||
66 | wait_queue_head_t wait; | ||
67 | u8 parent; | 56 | u8 parent; |
68 | }; | 57 | }; |
69 | 58 | ||
70 | #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw) | 59 | #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw) |
71 | 60 | ||
72 | static irqreturn_t clk_main_osc_irq_handler(int irq, void *dev_id) | 61 | static inline bool clk_main_osc_ready(struct regmap *regmap) |
73 | { | 62 | { |
74 | struct clk_main_osc *osc = dev_id; | 63 | unsigned int status; |
75 | 64 | ||
76 | wake_up(&osc->wait); | 65 | regmap_read(regmap, AT91_PMC_SR, &status); |
77 | disable_irq_nosync(osc->irq); | ||
78 | 66 | ||
79 | return IRQ_HANDLED; | 67 | return status & AT91_PMC_MOSCS; |
80 | } | 68 | } |
81 | 69 | ||
82 | static int clk_main_osc_prepare(struct clk_hw *hw) | 70 | static int clk_main_osc_prepare(struct clk_hw *hw) |
83 | { | 71 | { |
84 | struct clk_main_osc *osc = to_clk_main_osc(hw); | 72 | struct clk_main_osc *osc = to_clk_main_osc(hw); |
85 | struct at91_pmc *pmc = osc->pmc; | 73 | struct regmap *regmap = osc->regmap; |
86 | u32 tmp; | 74 | u32 tmp; |
87 | 75 | ||
88 | tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; | 76 | regmap_read(regmap, AT91_CKGR_MOR, &tmp); |
77 | tmp &= ~MOR_KEY_MASK; | ||
78 | |||
89 | if (tmp & AT91_PMC_OSCBYPASS) | 79 | if (tmp & AT91_PMC_OSCBYPASS) |
90 | return 0; | 80 | return 0; |
91 | 81 | ||
92 | if (!(tmp & AT91_PMC_MOSCEN)) { | 82 | if (!(tmp & AT91_PMC_MOSCEN)) { |
93 | tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY; | 83 | tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY; |
94 | pmc_write(pmc, AT91_CKGR_MOR, tmp); | 84 | regmap_write(regmap, AT91_CKGR_MOR, tmp); |
95 | } | 85 | } |
96 | 86 | ||
97 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) { | 87 | while (!clk_main_osc_ready(regmap)) |
98 | enable_irq(osc->irq); | 88 | cpu_relax(); |
99 | wait_event(osc->wait, | ||
100 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS); | ||
101 | } | ||
102 | 89 | ||
103 | return 0; | 90 | return 0; |
104 | } | 91 | } |
@@ -106,9 +93,10 @@ static int clk_main_osc_prepare(struct clk_hw *hw) | |||
106 | static void clk_main_osc_unprepare(struct clk_hw *hw) | 93 | static void clk_main_osc_unprepare(struct clk_hw *hw) |
107 | { | 94 | { |
108 | struct clk_main_osc *osc = to_clk_main_osc(hw); | 95 | struct clk_main_osc *osc = to_clk_main_osc(hw); |
109 | struct at91_pmc *pmc = osc->pmc; | 96 | struct regmap *regmap = osc->regmap; |
110 | u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); | 97 | u32 tmp; |
111 | 98 | ||
99 | regmap_read(regmap, AT91_CKGR_MOR, &tmp); | ||
112 | if (tmp & AT91_PMC_OSCBYPASS) | 100 | if (tmp & AT91_PMC_OSCBYPASS) |
113 | return; | 101 | return; |
114 | 102 | ||
@@ -116,20 +104,22 @@ static void clk_main_osc_unprepare(struct clk_hw *hw) | |||
116 | return; | 104 | return; |
117 | 105 | ||
118 | tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN); | 106 | tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN); |
119 | pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); | 107 | regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); |
120 | } | 108 | } |
121 | 109 | ||
122 | static int clk_main_osc_is_prepared(struct clk_hw *hw) | 110 | static int clk_main_osc_is_prepared(struct clk_hw *hw) |
123 | { | 111 | { |
124 | struct clk_main_osc *osc = to_clk_main_osc(hw); | 112 | struct clk_main_osc *osc = to_clk_main_osc(hw); |
125 | struct at91_pmc *pmc = osc->pmc; | 113 | struct regmap *regmap = osc->regmap; |
126 | u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); | 114 | u32 tmp, status; |
127 | 115 | ||
116 | regmap_read(regmap, AT91_CKGR_MOR, &tmp); | ||
128 | if (tmp & AT91_PMC_OSCBYPASS) | 117 | if (tmp & AT91_PMC_OSCBYPASS) |
129 | return 1; | 118 | return 1; |
130 | 119 | ||
131 | return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS) && | 120 | regmap_read(regmap, AT91_PMC_SR, &status); |
132 | (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN)); | 121 | |
122 | return (status & AT91_PMC_MOSCS) && (tmp & AT91_PMC_MOSCEN); | ||
133 | } | 123 | } |
134 | 124 | ||
135 | static const struct clk_ops main_osc_ops = { | 125 | static const struct clk_ops main_osc_ops = { |
@@ -139,18 +129,16 @@ static const struct clk_ops main_osc_ops = { | |||
139 | }; | 129 | }; |
140 | 130 | ||
141 | static struct clk * __init | 131 | static struct clk * __init |
142 | at91_clk_register_main_osc(struct at91_pmc *pmc, | 132 | at91_clk_register_main_osc(struct regmap *regmap, |
143 | unsigned int irq, | ||
144 | const char *name, | 133 | const char *name, |
145 | const char *parent_name, | 134 | const char *parent_name, |
146 | bool bypass) | 135 | bool bypass) |
147 | { | 136 | { |
148 | int ret; | ||
149 | struct clk_main_osc *osc; | 137 | struct clk_main_osc *osc; |
150 | struct clk *clk = NULL; | 138 | struct clk *clk = NULL; |
151 | struct clk_init_data init; | 139 | struct clk_init_data init; |
152 | 140 | ||
153 | if (!pmc || !irq || !name || !parent_name) | 141 | if (!name || !parent_name) |
154 | return ERR_PTR(-EINVAL); | 142 | return ERR_PTR(-EINVAL); |
155 | 143 | ||
156 | osc = kzalloc(sizeof(*osc), GFP_KERNEL); | 144 | osc = kzalloc(sizeof(*osc), GFP_KERNEL); |
@@ -164,85 +152,70 @@ at91_clk_register_main_osc(struct at91_pmc *pmc, | |||
164 | init.flags = CLK_IGNORE_UNUSED; | 152 | init.flags = CLK_IGNORE_UNUSED; |
165 | 153 | ||
166 | osc->hw.init = &init; | 154 | osc->hw.init = &init; |
167 | osc->pmc = pmc; | 155 | osc->regmap = regmap; |
168 | osc->irq = irq; | ||
169 | |||
170 | init_waitqueue_head(&osc->wait); | ||
171 | irq_set_status_flags(osc->irq, IRQ_NOAUTOEN); | ||
172 | ret = request_irq(osc->irq, clk_main_osc_irq_handler, | ||
173 | IRQF_TRIGGER_HIGH, name, osc); | ||
174 | if (ret) { | ||
175 | kfree(osc); | ||
176 | return ERR_PTR(ret); | ||
177 | } | ||
178 | 156 | ||
179 | if (bypass) | 157 | if (bypass) |
180 | pmc_write(pmc, AT91_CKGR_MOR, | 158 | regmap_update_bits(regmap, |
181 | (pmc_read(pmc, AT91_CKGR_MOR) & | 159 | AT91_CKGR_MOR, MOR_KEY_MASK | |
182 | ~(MOR_KEY_MASK | AT91_PMC_MOSCEN)) | | 160 | AT91_PMC_MOSCEN, |
183 | AT91_PMC_OSCBYPASS | AT91_PMC_KEY); | 161 | AT91_PMC_OSCBYPASS | AT91_PMC_KEY); |
184 | 162 | ||
185 | clk = clk_register(NULL, &osc->hw); | 163 | clk = clk_register(NULL, &osc->hw); |
186 | if (IS_ERR(clk)) { | 164 | if (IS_ERR(clk)) |
187 | free_irq(irq, osc); | ||
188 | kfree(osc); | 165 | kfree(osc); |
189 | } | ||
190 | 166 | ||
191 | return clk; | 167 | return clk; |
192 | } | 168 | } |
193 | 169 | ||
194 | void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np, | 170 | static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np) |
195 | struct at91_pmc *pmc) | ||
196 | { | 171 | { |
197 | struct clk *clk; | 172 | struct clk *clk; |
198 | unsigned int irq; | ||
199 | const char *name = np->name; | 173 | const char *name = np->name; |
200 | const char *parent_name; | 174 | const char *parent_name; |
175 | struct regmap *regmap; | ||
201 | bool bypass; | 176 | bool bypass; |
202 | 177 | ||
203 | of_property_read_string(np, "clock-output-names", &name); | 178 | of_property_read_string(np, "clock-output-names", &name); |
204 | bypass = of_property_read_bool(np, "atmel,osc-bypass"); | 179 | bypass = of_property_read_bool(np, "atmel,osc-bypass"); |
205 | parent_name = of_clk_get_parent_name(np, 0); | 180 | parent_name = of_clk_get_parent_name(np, 0); |
206 | 181 | ||
207 | irq = irq_of_parse_and_map(np, 0); | 182 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
208 | if (!irq) | 183 | if (IS_ERR(regmap)) |
209 | return; | 184 | return; |
210 | 185 | ||
211 | clk = at91_clk_register_main_osc(pmc, irq, name, parent_name, bypass); | 186 | clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass); |
212 | if (IS_ERR(clk)) | 187 | if (IS_ERR(clk)) |
213 | return; | 188 | return; |
214 | 189 | ||
215 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 190 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
216 | } | 191 | } |
192 | CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc", | ||
193 | of_at91rm9200_clk_main_osc_setup); | ||
217 | 194 | ||
218 | static irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id) | 195 | static bool clk_main_rc_osc_ready(struct regmap *regmap) |
219 | { | 196 | { |
220 | struct clk_main_rc_osc *osc = dev_id; | 197 | unsigned int status; |
221 | 198 | ||
222 | wake_up(&osc->wait); | 199 | regmap_read(regmap, AT91_PMC_SR, &status); |
223 | disable_irq_nosync(osc->irq); | ||
224 | 200 | ||
225 | return IRQ_HANDLED; | 201 | return status & AT91_PMC_MOSCRCS; |
226 | } | 202 | } |
227 | 203 | ||
228 | static int clk_main_rc_osc_prepare(struct clk_hw *hw) | 204 | static int clk_main_rc_osc_prepare(struct clk_hw *hw) |
229 | { | 205 | { |
230 | struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); | 206 | struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); |
231 | struct at91_pmc *pmc = osc->pmc; | 207 | struct regmap *regmap = osc->regmap; |
232 | u32 tmp; | 208 | unsigned int mor; |
233 | 209 | ||
234 | tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; | 210 | regmap_read(regmap, AT91_CKGR_MOR, &mor); |
235 | 211 | ||
236 | if (!(tmp & AT91_PMC_MOSCRCEN)) { | 212 | if (!(mor & AT91_PMC_MOSCRCEN)) |
237 | tmp |= AT91_PMC_MOSCRCEN | AT91_PMC_KEY; | 213 | regmap_update_bits(regmap, AT91_CKGR_MOR, |
238 | pmc_write(pmc, AT91_CKGR_MOR, tmp); | 214 | MOR_KEY_MASK | AT91_PMC_MOSCRCEN, |
239 | } | 215 | AT91_PMC_MOSCRCEN | AT91_PMC_KEY); |
240 | 216 | ||
241 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS)) { | 217 | while (!clk_main_rc_osc_ready(regmap)) |
242 | enable_irq(osc->irq); | 218 | cpu_relax(); |
243 | wait_event(osc->wait, | ||
244 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS); | ||
245 | } | ||
246 | 219 | ||
247 | return 0; | 220 | return 0; |
248 | } | 221 | } |
@@ -250,23 +223,28 @@ static int clk_main_rc_osc_prepare(struct clk_hw *hw) | |||
250 | static void clk_main_rc_osc_unprepare(struct clk_hw *hw) | 223 | static void clk_main_rc_osc_unprepare(struct clk_hw *hw) |
251 | { | 224 | { |
252 | struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); | 225 | struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); |
253 | struct at91_pmc *pmc = osc->pmc; | 226 | struct regmap *regmap = osc->regmap; |
254 | u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); | 227 | unsigned int mor; |
228 | |||
229 | regmap_read(regmap, AT91_CKGR_MOR, &mor); | ||
255 | 230 | ||
256 | if (!(tmp & AT91_PMC_MOSCRCEN)) | 231 | if (!(mor & AT91_PMC_MOSCRCEN)) |
257 | return; | 232 | return; |
258 | 233 | ||
259 | tmp &= ~(MOR_KEY_MASK | AT91_PMC_MOSCRCEN); | 234 | regmap_update_bits(regmap, AT91_CKGR_MOR, |
260 | pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); | 235 | MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY); |
261 | } | 236 | } |
262 | 237 | ||
263 | static int clk_main_rc_osc_is_prepared(struct clk_hw *hw) | 238 | static int clk_main_rc_osc_is_prepared(struct clk_hw *hw) |
264 | { | 239 | { |
265 | struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); | 240 | struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); |
266 | struct at91_pmc *pmc = osc->pmc; | 241 | struct regmap *regmap = osc->regmap; |
242 | unsigned int mor, status; | ||
267 | 243 | ||
268 | return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS) && | 244 | regmap_read(regmap, AT91_CKGR_MOR, &mor); |
269 | (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCRCEN)); | 245 | regmap_read(regmap, AT91_PMC_SR, &status); |
246 | |||
247 | return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS); | ||
270 | } | 248 | } |
271 | 249 | ||
272 | static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw, | 250 | static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw, |
@@ -294,17 +272,15 @@ static const struct clk_ops main_rc_osc_ops = { | |||
294 | }; | 272 | }; |
295 | 273 | ||
296 | static struct clk * __init | 274 | static struct clk * __init |
297 | at91_clk_register_main_rc_osc(struct at91_pmc *pmc, | 275 | at91_clk_register_main_rc_osc(struct regmap *regmap, |
298 | unsigned int irq, | ||
299 | const char *name, | 276 | const char *name, |
300 | u32 frequency, u32 accuracy) | 277 | u32 frequency, u32 accuracy) |
301 | { | 278 | { |
302 | int ret; | ||
303 | struct clk_main_rc_osc *osc; | 279 | struct clk_main_rc_osc *osc; |
304 | struct clk *clk = NULL; | 280 | struct clk *clk = NULL; |
305 | struct clk_init_data init; | 281 | struct clk_init_data init; |
306 | 282 | ||
307 | if (!pmc || !irq || !name || !frequency) | 283 | if (!name || !frequency) |
308 | return ERR_PTR(-EINVAL); | 284 | return ERR_PTR(-EINVAL); |
309 | 285 | ||
310 | osc = kzalloc(sizeof(*osc), GFP_KERNEL); | 286 | osc = kzalloc(sizeof(*osc), GFP_KERNEL); |
@@ -318,63 +294,53 @@ at91_clk_register_main_rc_osc(struct at91_pmc *pmc, | |||
318 | init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; | 294 | init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; |
319 | 295 | ||
320 | osc->hw.init = &init; | 296 | osc->hw.init = &init; |
321 | osc->pmc = pmc; | 297 | osc->regmap = regmap; |
322 | osc->irq = irq; | ||
323 | osc->frequency = frequency; | 298 | osc->frequency = frequency; |
324 | osc->accuracy = accuracy; | 299 | osc->accuracy = accuracy; |
325 | 300 | ||
326 | init_waitqueue_head(&osc->wait); | ||
327 | irq_set_status_flags(osc->irq, IRQ_NOAUTOEN); | ||
328 | ret = request_irq(osc->irq, clk_main_rc_osc_irq_handler, | ||
329 | IRQF_TRIGGER_HIGH, name, osc); | ||
330 | if (ret) | ||
331 | return ERR_PTR(ret); | ||
332 | |||
333 | clk = clk_register(NULL, &osc->hw); | 301 | clk = clk_register(NULL, &osc->hw); |
334 | if (IS_ERR(clk)) { | 302 | if (IS_ERR(clk)) |
335 | free_irq(irq, osc); | ||
336 | kfree(osc); | 303 | kfree(osc); |
337 | } | ||
338 | 304 | ||
339 | return clk; | 305 | return clk; |
340 | } | 306 | } |
341 | 307 | ||
342 | void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np, | 308 | static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np) |
343 | struct at91_pmc *pmc) | ||
344 | { | 309 | { |
345 | struct clk *clk; | 310 | struct clk *clk; |
346 | unsigned int irq; | ||
347 | u32 frequency = 0; | 311 | u32 frequency = 0; |
348 | u32 accuracy = 0; | 312 | u32 accuracy = 0; |
349 | const char *name = np->name; | 313 | const char *name = np->name; |
314 | struct regmap *regmap; | ||
350 | 315 | ||
351 | of_property_read_string(np, "clock-output-names", &name); | 316 | of_property_read_string(np, "clock-output-names", &name); |
352 | of_property_read_u32(np, "clock-frequency", &frequency); | 317 | of_property_read_u32(np, "clock-frequency", &frequency); |
353 | of_property_read_u32(np, "clock-accuracy", &accuracy); | 318 | of_property_read_u32(np, "clock-accuracy", &accuracy); |
354 | 319 | ||
355 | irq = irq_of_parse_and_map(np, 0); | 320 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
356 | if (!irq) | 321 | if (IS_ERR(regmap)) |
357 | return; | 322 | return; |
358 | 323 | ||
359 | clk = at91_clk_register_main_rc_osc(pmc, irq, name, frequency, | 324 | clk = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy); |
360 | accuracy); | ||
361 | if (IS_ERR(clk)) | 325 | if (IS_ERR(clk)) |
362 | return; | 326 | return; |
363 | 327 | ||
364 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 328 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
365 | } | 329 | } |
330 | CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc", | ||
331 | of_at91sam9x5_clk_main_rc_osc_setup); | ||
366 | 332 | ||
367 | 333 | ||
368 | static int clk_main_probe_frequency(struct at91_pmc *pmc) | 334 | static int clk_main_probe_frequency(struct regmap *regmap) |
369 | { | 335 | { |
370 | unsigned long prep_time, timeout; | 336 | unsigned long prep_time, timeout; |
371 | u32 tmp; | 337 | unsigned int mcfr; |
372 | 338 | ||
373 | timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT); | 339 | timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT); |
374 | do { | 340 | do { |
375 | prep_time = jiffies; | 341 | prep_time = jiffies; |
376 | tmp = pmc_read(pmc, AT91_CKGR_MCFR); | 342 | regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); |
377 | if (tmp & AT91_PMC_MAINRDY) | 343 | if (mcfr & AT91_PMC_MAINRDY) |
378 | return 0; | 344 | return 0; |
379 | usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); | 345 | usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); |
380 | } while (time_before(prep_time, timeout)); | 346 | } while (time_before(prep_time, timeout)); |
@@ -382,34 +348,37 @@ static int clk_main_probe_frequency(struct at91_pmc *pmc) | |||
382 | return -ETIMEDOUT; | 348 | return -ETIMEDOUT; |
383 | } | 349 | } |
384 | 350 | ||
385 | static unsigned long clk_main_recalc_rate(struct at91_pmc *pmc, | 351 | static unsigned long clk_main_recalc_rate(struct regmap *regmap, |
386 | unsigned long parent_rate) | 352 | unsigned long parent_rate) |
387 | { | 353 | { |
388 | u32 tmp; | 354 | unsigned int mcfr; |
389 | 355 | ||
390 | if (parent_rate) | 356 | if (parent_rate) |
391 | return parent_rate; | 357 | return parent_rate; |
392 | 358 | ||
393 | pr_warn("Main crystal frequency not set, using approximate value\n"); | 359 | pr_warn("Main crystal frequency not set, using approximate value\n"); |
394 | tmp = pmc_read(pmc, AT91_CKGR_MCFR); | 360 | regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); |
395 | if (!(tmp & AT91_PMC_MAINRDY)) | 361 | if (!(mcfr & AT91_PMC_MAINRDY)) |
396 | return 0; | 362 | return 0; |
397 | 363 | ||
398 | return ((tmp & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV; | 364 | return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV; |
399 | } | 365 | } |
400 | 366 | ||
401 | static int clk_rm9200_main_prepare(struct clk_hw *hw) | 367 | static int clk_rm9200_main_prepare(struct clk_hw *hw) |
402 | { | 368 | { |
403 | struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); | 369 | struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); |
404 | 370 | ||
405 | return clk_main_probe_frequency(clkmain->pmc); | 371 | return clk_main_probe_frequency(clkmain->regmap); |
406 | } | 372 | } |
407 | 373 | ||
408 | static int clk_rm9200_main_is_prepared(struct clk_hw *hw) | 374 | static int clk_rm9200_main_is_prepared(struct clk_hw *hw) |
409 | { | 375 | { |
410 | struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); | 376 | struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); |
377 | unsigned int status; | ||
378 | |||
379 | regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status); | ||
411 | 380 | ||
412 | return !!(pmc_read(clkmain->pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINRDY); | 381 | return status & AT91_PMC_MAINRDY ? 1 : 0; |
413 | } | 382 | } |
414 | 383 | ||
415 | static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, | 384 | static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, |
@@ -417,7 +386,7 @@ static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, | |||
417 | { | 386 | { |
418 | struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); | 387 | struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); |
419 | 388 | ||
420 | return clk_main_recalc_rate(clkmain->pmc, parent_rate); | 389 | return clk_main_recalc_rate(clkmain->regmap, parent_rate); |
421 | } | 390 | } |
422 | 391 | ||
423 | static const struct clk_ops rm9200_main_ops = { | 392 | static const struct clk_ops rm9200_main_ops = { |
@@ -427,7 +396,7 @@ static const struct clk_ops rm9200_main_ops = { | |||
427 | }; | 396 | }; |
428 | 397 | ||
429 | static struct clk * __init | 398 | static struct clk * __init |
430 | at91_clk_register_rm9200_main(struct at91_pmc *pmc, | 399 | at91_clk_register_rm9200_main(struct regmap *regmap, |
431 | const char *name, | 400 | const char *name, |
432 | const char *parent_name) | 401 | const char *parent_name) |
433 | { | 402 | { |
@@ -435,7 +404,7 @@ at91_clk_register_rm9200_main(struct at91_pmc *pmc, | |||
435 | struct clk *clk = NULL; | 404 | struct clk *clk = NULL; |
436 | struct clk_init_data init; | 405 | struct clk_init_data init; |
437 | 406 | ||
438 | if (!pmc || !name) | 407 | if (!name) |
439 | return ERR_PTR(-EINVAL); | 408 | return ERR_PTR(-EINVAL); |
440 | 409 | ||
441 | if (!parent_name) | 410 | if (!parent_name) |
@@ -452,7 +421,7 @@ at91_clk_register_rm9200_main(struct at91_pmc *pmc, | |||
452 | init.flags = 0; | 421 | init.flags = 0; |
453 | 422 | ||
454 | clkmain->hw.init = &init; | 423 | clkmain->hw.init = &init; |
455 | clkmain->pmc = pmc; | 424 | clkmain->regmap = regmap; |
456 | 425 | ||
457 | clk = clk_register(NULL, &clkmain->hw); | 426 | clk = clk_register(NULL, &clkmain->hw); |
458 | if (IS_ERR(clk)) | 427 | if (IS_ERR(clk)) |
@@ -461,52 +430,54 @@ at91_clk_register_rm9200_main(struct at91_pmc *pmc, | |||
461 | return clk; | 430 | return clk; |
462 | } | 431 | } |
463 | 432 | ||
464 | void __init of_at91rm9200_clk_main_setup(struct device_node *np, | 433 | static void __init of_at91rm9200_clk_main_setup(struct device_node *np) |
465 | struct at91_pmc *pmc) | ||
466 | { | 434 | { |
467 | struct clk *clk; | 435 | struct clk *clk; |
468 | const char *parent_name; | 436 | const char *parent_name; |
469 | const char *name = np->name; | 437 | const char *name = np->name; |
438 | struct regmap *regmap; | ||
470 | 439 | ||
471 | parent_name = of_clk_get_parent_name(np, 0); | 440 | parent_name = of_clk_get_parent_name(np, 0); |
472 | of_property_read_string(np, "clock-output-names", &name); | 441 | of_property_read_string(np, "clock-output-names", &name); |
473 | 442 | ||
474 | clk = at91_clk_register_rm9200_main(pmc, name, parent_name); | 443 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
444 | if (IS_ERR(regmap)) | ||
445 | return; | ||
446 | |||
447 | clk = at91_clk_register_rm9200_main(regmap, name, parent_name); | ||
475 | if (IS_ERR(clk)) | 448 | if (IS_ERR(clk)) |
476 | return; | 449 | return; |
477 | 450 | ||
478 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 451 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
479 | } | 452 | } |
453 | CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main", | ||
454 | of_at91rm9200_clk_main_setup); | ||
480 | 455 | ||
481 | static irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id) | 456 | static inline bool clk_sam9x5_main_ready(struct regmap *regmap) |
482 | { | 457 | { |
483 | struct clk_sam9x5_main *clkmain = dev_id; | 458 | unsigned int status; |
484 | 459 | ||
485 | wake_up(&clkmain->wait); | 460 | regmap_read(regmap, AT91_PMC_SR, &status); |
486 | disable_irq_nosync(clkmain->irq); | ||
487 | 461 | ||
488 | return IRQ_HANDLED; | 462 | return status & AT91_PMC_MOSCSELS ? 1 : 0; |
489 | } | 463 | } |
490 | 464 | ||
491 | static int clk_sam9x5_main_prepare(struct clk_hw *hw) | 465 | static int clk_sam9x5_main_prepare(struct clk_hw *hw) |
492 | { | 466 | { |
493 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); | 467 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); |
494 | struct at91_pmc *pmc = clkmain->pmc; | 468 | struct regmap *regmap = clkmain->regmap; |
495 | 469 | ||
496 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) { | 470 | while (!clk_sam9x5_main_ready(regmap)) |
497 | enable_irq(clkmain->irq); | 471 | cpu_relax(); |
498 | wait_event(clkmain->wait, | ||
499 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); | ||
500 | } | ||
501 | 472 | ||
502 | return clk_main_probe_frequency(pmc); | 473 | return clk_main_probe_frequency(regmap); |
503 | } | 474 | } |
504 | 475 | ||
505 | static int clk_sam9x5_main_is_prepared(struct clk_hw *hw) | 476 | static int clk_sam9x5_main_is_prepared(struct clk_hw *hw) |
506 | { | 477 | { |
507 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); | 478 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); |
508 | 479 | ||
509 | return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); | 480 | return clk_sam9x5_main_ready(clkmain->regmap); |
510 | } | 481 | } |
511 | 482 | ||
512 | static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw, | 483 | static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw, |
@@ -514,30 +485,28 @@ static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw, | |||
514 | { | 485 | { |
515 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); | 486 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); |
516 | 487 | ||
517 | return clk_main_recalc_rate(clkmain->pmc, parent_rate); | 488 | return clk_main_recalc_rate(clkmain->regmap, parent_rate); |
518 | } | 489 | } |
519 | 490 | ||
520 | static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index) | 491 | static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index) |
521 | { | 492 | { |
522 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); | 493 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); |
523 | struct at91_pmc *pmc = clkmain->pmc; | 494 | struct regmap *regmap = clkmain->regmap; |
524 | u32 tmp; | 495 | unsigned int tmp; |
525 | 496 | ||
526 | if (index > 1) | 497 | if (index > 1) |
527 | return -EINVAL; | 498 | return -EINVAL; |
528 | 499 | ||
529 | tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; | 500 | regmap_read(regmap, AT91_CKGR_MOR, &tmp); |
501 | tmp &= ~MOR_KEY_MASK; | ||
530 | 502 | ||
531 | if (index && !(tmp & AT91_PMC_MOSCSEL)) | 503 | if (index && !(tmp & AT91_PMC_MOSCSEL)) |
532 | pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL); | 504 | regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL); |
533 | else if (!index && (tmp & AT91_PMC_MOSCSEL)) | 505 | else if (!index && (tmp & AT91_PMC_MOSCSEL)) |
534 | pmc_write(pmc, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL); | 506 | regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL); |
535 | 507 | ||
536 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) { | 508 | while (!clk_sam9x5_main_ready(regmap)) |
537 | enable_irq(clkmain->irq); | 509 | cpu_relax(); |
538 | wait_event(clkmain->wait, | ||
539 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); | ||
540 | } | ||
541 | 510 | ||
542 | return 0; | 511 | return 0; |
543 | } | 512 | } |
@@ -545,8 +514,11 @@ static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index) | |||
545 | static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw) | 514 | static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw) |
546 | { | 515 | { |
547 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); | 516 | struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); |
517 | unsigned int status; | ||
518 | |||
519 | regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status); | ||
548 | 520 | ||
549 | return !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN); | 521 | return status & AT91_PMC_MOSCEN ? 1 : 0; |
550 | } | 522 | } |
551 | 523 | ||
552 | static const struct clk_ops sam9x5_main_ops = { | 524 | static const struct clk_ops sam9x5_main_ops = { |
@@ -558,18 +530,17 @@ static const struct clk_ops sam9x5_main_ops = { | |||
558 | }; | 530 | }; |
559 | 531 | ||
560 | static struct clk * __init | 532 | static struct clk * __init |
561 | at91_clk_register_sam9x5_main(struct at91_pmc *pmc, | 533 | at91_clk_register_sam9x5_main(struct regmap *regmap, |
562 | unsigned int irq, | ||
563 | const char *name, | 534 | const char *name, |
564 | const char **parent_names, | 535 | const char **parent_names, |
565 | int num_parents) | 536 | int num_parents) |
566 | { | 537 | { |
567 | int ret; | ||
568 | struct clk_sam9x5_main *clkmain; | 538 | struct clk_sam9x5_main *clkmain; |
569 | struct clk *clk = NULL; | 539 | struct clk *clk = NULL; |
570 | struct clk_init_data init; | 540 | struct clk_init_data init; |
541 | unsigned int status; | ||
571 | 542 | ||
572 | if (!pmc || !irq || !name) | 543 | if (!name) |
573 | return ERR_PTR(-EINVAL); | 544 | return ERR_PTR(-EINVAL); |
574 | 545 | ||
575 | if (!parent_names || !num_parents) | 546 | if (!parent_names || !num_parents) |
@@ -586,51 +557,42 @@ at91_clk_register_sam9x5_main(struct at91_pmc *pmc, | |||
586 | init.flags = CLK_SET_PARENT_GATE; | 557 | init.flags = CLK_SET_PARENT_GATE; |
587 | 558 | ||
588 | clkmain->hw.init = &init; | 559 | clkmain->hw.init = &init; |
589 | clkmain->pmc = pmc; | 560 | clkmain->regmap = regmap; |
590 | clkmain->irq = irq; | 561 | regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status); |
591 | clkmain->parent = !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & | 562 | clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0; |
592 | AT91_PMC_MOSCEN); | ||
593 | init_waitqueue_head(&clkmain->wait); | ||
594 | irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN); | ||
595 | ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler, | ||
596 | IRQF_TRIGGER_HIGH, name, clkmain); | ||
597 | if (ret) | ||
598 | return ERR_PTR(ret); | ||
599 | 563 | ||
600 | clk = clk_register(NULL, &clkmain->hw); | 564 | clk = clk_register(NULL, &clkmain->hw); |
601 | if (IS_ERR(clk)) { | 565 | if (IS_ERR(clk)) |
602 | free_irq(clkmain->irq, clkmain); | ||
603 | kfree(clkmain); | 566 | kfree(clkmain); |
604 | } | ||
605 | 567 | ||
606 | return clk; | 568 | return clk; |
607 | } | 569 | } |
608 | 570 | ||
609 | void __init of_at91sam9x5_clk_main_setup(struct device_node *np, | 571 | static void __init of_at91sam9x5_clk_main_setup(struct device_node *np) |
610 | struct at91_pmc *pmc) | ||
611 | { | 572 | { |
612 | struct clk *clk; | 573 | struct clk *clk; |
613 | const char *parent_names[2]; | 574 | const char *parent_names[2]; |
614 | int num_parents; | 575 | int num_parents; |
615 | unsigned int irq; | ||
616 | const char *name = np->name; | 576 | const char *name = np->name; |
577 | struct regmap *regmap; | ||
617 | 578 | ||
618 | num_parents = of_clk_get_parent_count(np); | 579 | num_parents = of_clk_get_parent_count(np); |
619 | if (num_parents <= 0 || num_parents > 2) | 580 | if (num_parents <= 0 || num_parents > 2) |
620 | return; | 581 | return; |
621 | 582 | ||
622 | of_clk_parent_fill(np, parent_names, num_parents); | 583 | of_clk_parent_fill(np, parent_names, num_parents); |
584 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
585 | if (IS_ERR(regmap)) | ||
586 | return; | ||
623 | 587 | ||
624 | of_property_read_string(np, "clock-output-names", &name); | 588 | of_property_read_string(np, "clock-output-names", &name); |
625 | 589 | ||
626 | irq = irq_of_parse_and_map(np, 0); | 590 | clk = at91_clk_register_sam9x5_main(regmap, name, parent_names, |
627 | if (!irq) | ||
628 | return; | ||
629 | |||
630 | clk = at91_clk_register_sam9x5_main(pmc, irq, name, parent_names, | ||
631 | num_parents); | 591 | num_parents); |
632 | if (IS_ERR(clk)) | 592 | if (IS_ERR(clk)) |
633 | return; | 593 | return; |
634 | 594 | ||
635 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 595 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
636 | } | 596 | } |
597 | CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main", | ||
598 | of_at91sam9x5_clk_main_setup); | ||
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index 620ea323356b..7d4a1864ea7c 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c | |||
@@ -12,13 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/of_irq.h> | 16 | #include <linux/regmap.h> |
17 | #include <linux/io.h> | ||
18 | #include <linux/wait.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/irq.h> | ||
22 | 17 | ||
23 | #include "pmc.h" | 18 | #include "pmc.h" |
24 | 19 | ||
@@ -44,32 +39,26 @@ struct clk_master_layout { | |||
44 | 39 | ||
45 | struct clk_master { | 40 | struct clk_master { |
46 | struct clk_hw hw; | 41 | struct clk_hw hw; |
47 | struct at91_pmc *pmc; | 42 | struct regmap *regmap; |
48 | unsigned int irq; | ||
49 | wait_queue_head_t wait; | ||
50 | const struct clk_master_layout *layout; | 43 | const struct clk_master_layout *layout; |
51 | const struct clk_master_characteristics *characteristics; | 44 | const struct clk_master_characteristics *characteristics; |
52 | }; | 45 | }; |
53 | 46 | ||
54 | static irqreturn_t clk_master_irq_handler(int irq, void *dev_id) | 47 | static inline bool clk_master_ready(struct regmap *regmap) |
55 | { | 48 | { |
56 | struct clk_master *master = (struct clk_master *)dev_id; | 49 | unsigned int status; |
57 | 50 | ||
58 | wake_up(&master->wait); | 51 | regmap_read(regmap, AT91_PMC_SR, &status); |
59 | disable_irq_nosync(master->irq); | ||
60 | 52 | ||
61 | return IRQ_HANDLED; | 53 | return status & AT91_PMC_MCKRDY ? 1 : 0; |
62 | } | 54 | } |
55 | |||
63 | static int clk_master_prepare(struct clk_hw *hw) | 56 | static int clk_master_prepare(struct clk_hw *hw) |
64 | { | 57 | { |
65 | struct clk_master *master = to_clk_master(hw); | 58 | struct clk_master *master = to_clk_master(hw); |
66 | struct at91_pmc *pmc = master->pmc; | ||
67 | 59 | ||
68 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) { | 60 | while (!clk_master_ready(master->regmap)) |
69 | enable_irq(master->irq); | 61 | cpu_relax(); |
70 | wait_event(master->wait, | ||
71 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY); | ||
72 | } | ||
73 | 62 | ||
74 | return 0; | 63 | return 0; |
75 | } | 64 | } |
@@ -78,7 +67,7 @@ static int clk_master_is_prepared(struct clk_hw *hw) | |||
78 | { | 67 | { |
79 | struct clk_master *master = to_clk_master(hw); | 68 | struct clk_master *master = to_clk_master(hw); |
80 | 69 | ||
81 | return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY); | 70 | return clk_master_ready(master->regmap); |
82 | } | 71 | } |
83 | 72 | ||
84 | static unsigned long clk_master_recalc_rate(struct clk_hw *hw, | 73 | static unsigned long clk_master_recalc_rate(struct clk_hw *hw, |
@@ -88,18 +77,16 @@ static unsigned long clk_master_recalc_rate(struct clk_hw *hw, | |||
88 | u8 div; | 77 | u8 div; |
89 | unsigned long rate = parent_rate; | 78 | unsigned long rate = parent_rate; |
90 | struct clk_master *master = to_clk_master(hw); | 79 | struct clk_master *master = to_clk_master(hw); |
91 | struct at91_pmc *pmc = master->pmc; | ||
92 | const struct clk_master_layout *layout = master->layout; | 80 | const struct clk_master_layout *layout = master->layout; |
93 | const struct clk_master_characteristics *characteristics = | 81 | const struct clk_master_characteristics *characteristics = |
94 | master->characteristics; | 82 | master->characteristics; |
95 | u32 tmp; | 83 | unsigned int mckr; |
96 | 84 | ||
97 | pmc_lock(pmc); | 85 | regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); |
98 | tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask; | 86 | mckr &= layout->mask; |
99 | pmc_unlock(pmc); | ||
100 | 87 | ||
101 | pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK; | 88 | pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; |
102 | div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; | 89 | div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; |
103 | 90 | ||
104 | if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) | 91 | if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) |
105 | rate /= 3; | 92 | rate /= 3; |
@@ -119,9 +106,11 @@ static unsigned long clk_master_recalc_rate(struct clk_hw *hw, | |||
119 | static u8 clk_master_get_parent(struct clk_hw *hw) | 106 | static u8 clk_master_get_parent(struct clk_hw *hw) |
120 | { | 107 | { |
121 | struct clk_master *master = to_clk_master(hw); | 108 | struct clk_master *master = to_clk_master(hw); |
122 | struct at91_pmc *pmc = master->pmc; | 109 | unsigned int mckr; |
123 | 110 | ||
124 | return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS; | 111 | regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); |
112 | |||
113 | return mckr & AT91_PMC_CSS; | ||
125 | } | 114 | } |
126 | 115 | ||
127 | static const struct clk_ops master_ops = { | 116 | static const struct clk_ops master_ops = { |
@@ -132,18 +121,17 @@ static const struct clk_ops master_ops = { | |||
132 | }; | 121 | }; |
133 | 122 | ||
134 | static struct clk * __init | 123 | static struct clk * __init |
135 | at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq, | 124 | at91_clk_register_master(struct regmap *regmap, |
136 | const char *name, int num_parents, | 125 | const char *name, int num_parents, |
137 | const char **parent_names, | 126 | const char **parent_names, |
138 | const struct clk_master_layout *layout, | 127 | const struct clk_master_layout *layout, |
139 | const struct clk_master_characteristics *characteristics) | 128 | const struct clk_master_characteristics *characteristics) |
140 | { | 129 | { |
141 | int ret; | ||
142 | struct clk_master *master; | 130 | struct clk_master *master; |
143 | struct clk *clk = NULL; | 131 | struct clk *clk = NULL; |
144 | struct clk_init_data init; | 132 | struct clk_init_data init; |
145 | 133 | ||
146 | if (!pmc || !irq || !name || !num_parents || !parent_names) | 134 | if (!name || !num_parents || !parent_names) |
147 | return ERR_PTR(-EINVAL); | 135 | return ERR_PTR(-EINVAL); |
148 | 136 | ||
149 | master = kzalloc(sizeof(*master), GFP_KERNEL); | 137 | master = kzalloc(sizeof(*master), GFP_KERNEL); |
@@ -159,20 +147,10 @@ at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq, | |||
159 | master->hw.init = &init; | 147 | master->hw.init = &init; |
160 | master->layout = layout; | 148 | master->layout = layout; |
161 | master->characteristics = characteristics; | 149 | master->characteristics = characteristics; |
162 | master->pmc = pmc; | 150 | master->regmap = regmap; |
163 | master->irq = irq; | ||
164 | init_waitqueue_head(&master->wait); | ||
165 | irq_set_status_flags(master->irq, IRQ_NOAUTOEN); | ||
166 | ret = request_irq(master->irq, clk_master_irq_handler, | ||
167 | IRQF_TRIGGER_HIGH, "clk-master", master); | ||
168 | if (ret) { | ||
169 | kfree(master); | ||
170 | return ERR_PTR(ret); | ||
171 | } | ||
172 | 151 | ||
173 | clk = clk_register(NULL, &master->hw); | 152 | clk = clk_register(NULL, &master->hw); |
174 | if (IS_ERR(clk)) { | 153 | if (IS_ERR(clk)) { |
175 | free_irq(master->irq, master); | ||
176 | kfree(master); | 154 | kfree(master); |
177 | } | 155 | } |
178 | 156 | ||
@@ -217,15 +195,15 @@ out_free_characteristics: | |||
217 | } | 195 | } |
218 | 196 | ||
219 | static void __init | 197 | static void __init |
220 | of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, | 198 | of_at91_clk_master_setup(struct device_node *np, |
221 | const struct clk_master_layout *layout) | 199 | const struct clk_master_layout *layout) |
222 | { | 200 | { |
223 | struct clk *clk; | 201 | struct clk *clk; |
224 | int num_parents; | 202 | int num_parents; |
225 | unsigned int irq; | ||
226 | const char *parent_names[MASTER_SOURCE_MAX]; | 203 | const char *parent_names[MASTER_SOURCE_MAX]; |
227 | const char *name = np->name; | 204 | const char *name = np->name; |
228 | struct clk_master_characteristics *characteristics; | 205 | struct clk_master_characteristics *characteristics; |
206 | struct regmap *regmap; | ||
229 | 207 | ||
230 | num_parents = of_clk_get_parent_count(np); | 208 | num_parents = of_clk_get_parent_count(np); |
231 | if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX) | 209 | if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX) |
@@ -239,11 +217,11 @@ of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, | |||
239 | if (!characteristics) | 217 | if (!characteristics) |
240 | return; | 218 | return; |
241 | 219 | ||
242 | irq = irq_of_parse_and_map(np, 0); | 220 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
243 | if (!irq) | 221 | if (IS_ERR(regmap)) |
244 | goto out_free_characteristics; | 222 | return; |
245 | 223 | ||
246 | clk = at91_clk_register_master(pmc, irq, name, num_parents, | 224 | clk = at91_clk_register_master(regmap, name, num_parents, |
247 | parent_names, layout, | 225 | parent_names, layout, |
248 | characteristics); | 226 | characteristics); |
249 | if (IS_ERR(clk)) | 227 | if (IS_ERR(clk)) |
@@ -256,14 +234,16 @@ out_free_characteristics: | |||
256 | kfree(characteristics); | 234 | kfree(characteristics); |
257 | } | 235 | } |
258 | 236 | ||
259 | void __init of_at91rm9200_clk_master_setup(struct device_node *np, | 237 | static void __init of_at91rm9200_clk_master_setup(struct device_node *np) |
260 | struct at91_pmc *pmc) | ||
261 | { | 238 | { |
262 | of_at91_clk_master_setup(np, pmc, &at91rm9200_master_layout); | 239 | of_at91_clk_master_setup(np, &at91rm9200_master_layout); |
263 | } | 240 | } |
241 | CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master", | ||
242 | of_at91rm9200_clk_master_setup); | ||
264 | 243 | ||
265 | void __init of_at91sam9x5_clk_master_setup(struct device_node *np, | 244 | static void __init of_at91sam9x5_clk_master_setup(struct device_node *np) |
266 | struct at91_pmc *pmc) | ||
267 | { | 245 | { |
268 | of_at91_clk_master_setup(np, pmc, &at91sam9x5_master_layout); | 246 | of_at91_clk_master_setup(np, &at91sam9x5_master_layout); |
269 | } | 247 | } |
248 | CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master", | ||
249 | of_at91sam9x5_clk_master_setup); | ||
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index 58f3b568e9cb..fd160728e990 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c | |||
@@ -12,11 +12,13 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/io.h> | 16 | #include <linux/regmap.h> |
17 | 17 | ||
18 | #include "pmc.h" | 18 | #include "pmc.h" |
19 | 19 | ||
20 | DEFINE_SPINLOCK(pmc_pcr_lock); | ||
21 | |||
20 | #define PERIPHERAL_MAX 64 | 22 | #define PERIPHERAL_MAX 64 |
21 | 23 | ||
22 | #define PERIPHERAL_AT91RM9200 0 | 24 | #define PERIPHERAL_AT91RM9200 0 |
@@ -33,7 +35,7 @@ | |||
33 | 35 | ||
34 | struct clk_peripheral { | 36 | struct clk_peripheral { |
35 | struct clk_hw hw; | 37 | struct clk_hw hw; |
36 | struct at91_pmc *pmc; | 38 | struct regmap *regmap; |
37 | u32 id; | 39 | u32 id; |
38 | }; | 40 | }; |
39 | 41 | ||
@@ -41,8 +43,9 @@ struct clk_peripheral { | |||
41 | 43 | ||
42 | struct clk_sam9x5_peripheral { | 44 | struct clk_sam9x5_peripheral { |
43 | struct clk_hw hw; | 45 | struct clk_hw hw; |
44 | struct at91_pmc *pmc; | 46 | struct regmap *regmap; |
45 | struct clk_range range; | 47 | struct clk_range range; |
48 | spinlock_t *lock; | ||
46 | u32 id; | 49 | u32 id; |
47 | u32 div; | 50 | u32 div; |
48 | bool auto_div; | 51 | bool auto_div; |
@@ -54,7 +57,6 @@ struct clk_sam9x5_peripheral { | |||
54 | static int clk_peripheral_enable(struct clk_hw *hw) | 57 | static int clk_peripheral_enable(struct clk_hw *hw) |
55 | { | 58 | { |
56 | struct clk_peripheral *periph = to_clk_peripheral(hw); | 59 | struct clk_peripheral *periph = to_clk_peripheral(hw); |
57 | struct at91_pmc *pmc = periph->pmc; | ||
58 | int offset = AT91_PMC_PCER; | 60 | int offset = AT91_PMC_PCER; |
59 | u32 id = periph->id; | 61 | u32 id = periph->id; |
60 | 62 | ||
@@ -62,14 +64,14 @@ static int clk_peripheral_enable(struct clk_hw *hw) | |||
62 | return 0; | 64 | return 0; |
63 | if (id > PERIPHERAL_ID_MAX) | 65 | if (id > PERIPHERAL_ID_MAX) |
64 | offset = AT91_PMC_PCER1; | 66 | offset = AT91_PMC_PCER1; |
65 | pmc_write(pmc, offset, PERIPHERAL_MASK(id)); | 67 | regmap_write(periph->regmap, offset, PERIPHERAL_MASK(id)); |
68 | |||
66 | return 0; | 69 | return 0; |
67 | } | 70 | } |
68 | 71 | ||
69 | static void clk_peripheral_disable(struct clk_hw *hw) | 72 | static void clk_peripheral_disable(struct clk_hw *hw) |
70 | { | 73 | { |
71 | struct clk_peripheral *periph = to_clk_peripheral(hw); | 74 | struct clk_peripheral *periph = to_clk_peripheral(hw); |
72 | struct at91_pmc *pmc = periph->pmc; | ||
73 | int offset = AT91_PMC_PCDR; | 75 | int offset = AT91_PMC_PCDR; |
74 | u32 id = periph->id; | 76 | u32 id = periph->id; |
75 | 77 | ||
@@ -77,21 +79,23 @@ static void clk_peripheral_disable(struct clk_hw *hw) | |||
77 | return; | 79 | return; |
78 | if (id > PERIPHERAL_ID_MAX) | 80 | if (id > PERIPHERAL_ID_MAX) |
79 | offset = AT91_PMC_PCDR1; | 81 | offset = AT91_PMC_PCDR1; |
80 | pmc_write(pmc, offset, PERIPHERAL_MASK(id)); | 82 | regmap_write(periph->regmap, offset, PERIPHERAL_MASK(id)); |
81 | } | 83 | } |
82 | 84 | ||
83 | static int clk_peripheral_is_enabled(struct clk_hw *hw) | 85 | static int clk_peripheral_is_enabled(struct clk_hw *hw) |
84 | { | 86 | { |
85 | struct clk_peripheral *periph = to_clk_peripheral(hw); | 87 | struct clk_peripheral *periph = to_clk_peripheral(hw); |
86 | struct at91_pmc *pmc = periph->pmc; | ||
87 | int offset = AT91_PMC_PCSR; | 88 | int offset = AT91_PMC_PCSR; |
89 | unsigned int status; | ||
88 | u32 id = periph->id; | 90 | u32 id = periph->id; |
89 | 91 | ||
90 | if (id < PERIPHERAL_ID_MIN) | 92 | if (id < PERIPHERAL_ID_MIN) |
91 | return 1; | 93 | return 1; |
92 | if (id > PERIPHERAL_ID_MAX) | 94 | if (id > PERIPHERAL_ID_MAX) |
93 | offset = AT91_PMC_PCSR1; | 95 | offset = AT91_PMC_PCSR1; |
94 | return !!(pmc_read(pmc, offset) & PERIPHERAL_MASK(id)); | 96 | regmap_read(periph->regmap, offset, &status); |
97 | |||
98 | return status & PERIPHERAL_MASK(id) ? 1 : 0; | ||
95 | } | 99 | } |
96 | 100 | ||
97 | static const struct clk_ops peripheral_ops = { | 101 | static const struct clk_ops peripheral_ops = { |
@@ -101,14 +105,14 @@ static const struct clk_ops peripheral_ops = { | |||
101 | }; | 105 | }; |
102 | 106 | ||
103 | static struct clk * __init | 107 | static struct clk * __init |
104 | at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name, | 108 | at91_clk_register_peripheral(struct regmap *regmap, const char *name, |
105 | const char *parent_name, u32 id) | 109 | const char *parent_name, u32 id) |
106 | { | 110 | { |
107 | struct clk_peripheral *periph; | 111 | struct clk_peripheral *periph; |
108 | struct clk *clk = NULL; | 112 | struct clk *clk = NULL; |
109 | struct clk_init_data init; | 113 | struct clk_init_data init; |
110 | 114 | ||
111 | if (!pmc || !name || !parent_name || id > PERIPHERAL_ID_MAX) | 115 | if (!name || !parent_name || id > PERIPHERAL_ID_MAX) |
112 | return ERR_PTR(-EINVAL); | 116 | return ERR_PTR(-EINVAL); |
113 | 117 | ||
114 | periph = kzalloc(sizeof(*periph), GFP_KERNEL); | 118 | periph = kzalloc(sizeof(*periph), GFP_KERNEL); |
@@ -123,7 +127,7 @@ at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name, | |||
123 | 127 | ||
124 | periph->id = id; | 128 | periph->id = id; |
125 | periph->hw.init = &init; | 129 | periph->hw.init = &init; |
126 | periph->pmc = pmc; | 130 | periph->regmap = regmap; |
127 | 131 | ||
128 | clk = clk_register(NULL, &periph->hw); | 132 | clk = clk_register(NULL, &periph->hw); |
129 | if (IS_ERR(clk)) | 133 | if (IS_ERR(clk)) |
@@ -160,53 +164,58 @@ static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph) | |||
160 | static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) | 164 | static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) |
161 | { | 165 | { |
162 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | 166 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); |
163 | struct at91_pmc *pmc = periph->pmc; | 167 | unsigned long flags; |
164 | u32 tmp; | ||
165 | 168 | ||
166 | if (periph->id < PERIPHERAL_ID_MIN) | 169 | if (periph->id < PERIPHERAL_ID_MIN) |
167 | return 0; | 170 | return 0; |
168 | 171 | ||
169 | pmc_lock(pmc); | 172 | spin_lock_irqsave(periph->lock, flags); |
170 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); | 173 | regmap_write(periph->regmap, AT91_PMC_PCR, |
171 | tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK; | 174 | (periph->id & AT91_PMC_PCR_PID_MASK)); |
172 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div) | 175 | regmap_update_bits(periph->regmap, AT91_PMC_PCR, |
173 | | AT91_PMC_PCR_CMD | 176 | AT91_PMC_PCR_DIV_MASK | AT91_PMC_PCR_CMD | |
174 | | AT91_PMC_PCR_EN); | 177 | AT91_PMC_PCR_EN, |
175 | pmc_unlock(pmc); | 178 | AT91_PMC_PCR_DIV(periph->div) | |
179 | AT91_PMC_PCR_CMD | | ||
180 | AT91_PMC_PCR_EN); | ||
181 | spin_unlock_irqrestore(periph->lock, flags); | ||
182 | |||
176 | return 0; | 183 | return 0; |
177 | } | 184 | } |
178 | 185 | ||
179 | static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) | 186 | static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) |
180 | { | 187 | { |
181 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | 188 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); |
182 | struct at91_pmc *pmc = periph->pmc; | 189 | unsigned long flags; |
183 | u32 tmp; | ||
184 | 190 | ||
185 | if (periph->id < PERIPHERAL_ID_MIN) | 191 | if (periph->id < PERIPHERAL_ID_MIN) |
186 | return; | 192 | return; |
187 | 193 | ||
188 | pmc_lock(pmc); | 194 | spin_lock_irqsave(periph->lock, flags); |
189 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); | 195 | regmap_write(periph->regmap, AT91_PMC_PCR, |
190 | tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN; | 196 | (periph->id & AT91_PMC_PCR_PID_MASK)); |
191 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD); | 197 | regmap_update_bits(periph->regmap, AT91_PMC_PCR, |
192 | pmc_unlock(pmc); | 198 | AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD, |
199 | AT91_PMC_PCR_CMD); | ||
200 | spin_unlock_irqrestore(periph->lock, flags); | ||
193 | } | 201 | } |
194 | 202 | ||
195 | static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) | 203 | static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) |
196 | { | 204 | { |
197 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | 205 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); |
198 | struct at91_pmc *pmc = periph->pmc; | 206 | unsigned long flags; |
199 | int ret; | 207 | unsigned int status; |
200 | 208 | ||
201 | if (periph->id < PERIPHERAL_ID_MIN) | 209 | if (periph->id < PERIPHERAL_ID_MIN) |
202 | return 1; | 210 | return 1; |
203 | 211 | ||
204 | pmc_lock(pmc); | 212 | spin_lock_irqsave(periph->lock, flags); |
205 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); | 213 | regmap_write(periph->regmap, AT91_PMC_PCR, |
206 | ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN); | 214 | (periph->id & AT91_PMC_PCR_PID_MASK)); |
207 | pmc_unlock(pmc); | 215 | regmap_read(periph->regmap, AT91_PMC_PCR, &status); |
216 | spin_unlock_irqrestore(periph->lock, flags); | ||
208 | 217 | ||
209 | return ret; | 218 | return status & AT91_PMC_PCR_EN ? 1 : 0; |
210 | } | 219 | } |
211 | 220 | ||
212 | static unsigned long | 221 | static unsigned long |
@@ -214,19 +223,20 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw, | |||
214 | unsigned long parent_rate) | 223 | unsigned long parent_rate) |
215 | { | 224 | { |
216 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | 225 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); |
217 | struct at91_pmc *pmc = periph->pmc; | 226 | unsigned long flags; |
218 | u32 tmp; | 227 | unsigned int status; |
219 | 228 | ||
220 | if (periph->id < PERIPHERAL_ID_MIN) | 229 | if (periph->id < PERIPHERAL_ID_MIN) |
221 | return parent_rate; | 230 | return parent_rate; |
222 | 231 | ||
223 | pmc_lock(pmc); | 232 | spin_lock_irqsave(periph->lock, flags); |
224 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); | 233 | regmap_write(periph->regmap, AT91_PMC_PCR, |
225 | tmp = pmc_read(pmc, AT91_PMC_PCR); | 234 | (periph->id & AT91_PMC_PCR_PID_MASK)); |
226 | pmc_unlock(pmc); | 235 | regmap_read(periph->regmap, AT91_PMC_PCR, &status); |
236 | spin_unlock_irqrestore(periph->lock, flags); | ||
227 | 237 | ||
228 | if (tmp & AT91_PMC_PCR_EN) { | 238 | if (status & AT91_PMC_PCR_EN) { |
229 | periph->div = PERIPHERAL_RSHIFT(tmp); | 239 | periph->div = PERIPHERAL_RSHIFT(status); |
230 | periph->auto_div = false; | 240 | periph->auto_div = false; |
231 | } else { | 241 | } else { |
232 | clk_sam9x5_peripheral_autodiv(periph); | 242 | clk_sam9x5_peripheral_autodiv(periph); |
@@ -318,15 +328,15 @@ static const struct clk_ops sam9x5_peripheral_ops = { | |||
318 | }; | 328 | }; |
319 | 329 | ||
320 | static struct clk * __init | 330 | static struct clk * __init |
321 | at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name, | 331 | at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, |
322 | const char *parent_name, u32 id, | 332 | const char *name, const char *parent_name, |
323 | const struct clk_range *range) | 333 | u32 id, const struct clk_range *range) |
324 | { | 334 | { |
325 | struct clk_sam9x5_peripheral *periph; | 335 | struct clk_sam9x5_peripheral *periph; |
326 | struct clk *clk = NULL; | 336 | struct clk *clk = NULL; |
327 | struct clk_init_data init; | 337 | struct clk_init_data init; |
328 | 338 | ||
329 | if (!pmc || !name || !parent_name) | 339 | if (!name || !parent_name) |
330 | return ERR_PTR(-EINVAL); | 340 | return ERR_PTR(-EINVAL); |
331 | 341 | ||
332 | periph = kzalloc(sizeof(*periph), GFP_KERNEL); | 342 | periph = kzalloc(sizeof(*periph), GFP_KERNEL); |
@@ -342,7 +352,8 @@ at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name, | |||
342 | periph->id = id; | 352 | periph->id = id; |
343 | periph->hw.init = &init; | 353 | periph->hw.init = &init; |
344 | periph->div = 0; | 354 | periph->div = 0; |
345 | periph->pmc = pmc; | 355 | periph->regmap = regmap; |
356 | periph->lock = lock; | ||
346 | periph->auto_div = true; | 357 | periph->auto_div = true; |
347 | periph->range = *range; | 358 | periph->range = *range; |
348 | 359 | ||
@@ -356,7 +367,7 @@ at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name, | |||
356 | } | 367 | } |
357 | 368 | ||
358 | static void __init | 369 | static void __init |
359 | of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) | 370 | of_at91_clk_periph_setup(struct device_node *np, u8 type) |
360 | { | 371 | { |
361 | int num; | 372 | int num; |
362 | u32 id; | 373 | u32 id; |
@@ -364,6 +375,7 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) | |||
364 | const char *parent_name; | 375 | const char *parent_name; |
365 | const char *name; | 376 | const char *name; |
366 | struct device_node *periphclknp; | 377 | struct device_node *periphclknp; |
378 | struct regmap *regmap; | ||
367 | 379 | ||
368 | parent_name = of_clk_get_parent_name(np, 0); | 380 | parent_name = of_clk_get_parent_name(np, 0); |
369 | if (!parent_name) | 381 | if (!parent_name) |
@@ -373,6 +385,10 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) | |||
373 | if (!num || num > PERIPHERAL_MAX) | 385 | if (!num || num > PERIPHERAL_MAX) |
374 | return; | 386 | return; |
375 | 387 | ||
388 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
389 | if (IS_ERR(regmap)) | ||
390 | return; | ||
391 | |||
376 | for_each_child_of_node(np, periphclknp) { | 392 | for_each_child_of_node(np, periphclknp) { |
377 | if (of_property_read_u32(periphclknp, "reg", &id)) | 393 | if (of_property_read_u32(periphclknp, "reg", &id)) |
378 | continue; | 394 | continue; |
@@ -384,7 +400,7 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) | |||
384 | name = periphclknp->name; | 400 | name = periphclknp->name; |
385 | 401 | ||
386 | if (type == PERIPHERAL_AT91RM9200) { | 402 | if (type == PERIPHERAL_AT91RM9200) { |
387 | clk = at91_clk_register_peripheral(pmc, name, | 403 | clk = at91_clk_register_peripheral(regmap, name, |
388 | parent_name, id); | 404 | parent_name, id); |
389 | } else { | 405 | } else { |
390 | struct clk_range range = CLK_RANGE(0, 0); | 406 | struct clk_range range = CLK_RANGE(0, 0); |
@@ -393,7 +409,9 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) | |||
393 | "atmel,clk-output-range", | 409 | "atmel,clk-output-range", |
394 | &range); | 410 | &range); |
395 | 411 | ||
396 | clk = at91_clk_register_sam9x5_peripheral(pmc, name, | 412 | clk = at91_clk_register_sam9x5_peripheral(regmap, |
413 | &pmc_pcr_lock, | ||
414 | name, | ||
397 | parent_name, | 415 | parent_name, |
398 | id, &range); | 416 | id, &range); |
399 | } | 417 | } |
@@ -405,14 +423,17 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) | |||
405 | } | 423 | } |
406 | } | 424 | } |
407 | 425 | ||
408 | void __init of_at91rm9200_clk_periph_setup(struct device_node *np, | 426 | static void __init of_at91rm9200_clk_periph_setup(struct device_node *np) |
409 | struct at91_pmc *pmc) | ||
410 | { | 427 | { |
411 | of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91RM9200); | 428 | of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200); |
412 | } | 429 | } |
430 | CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral", | ||
431 | of_at91rm9200_clk_periph_setup); | ||
413 | 432 | ||
414 | void __init of_at91sam9x5_clk_periph_setup(struct device_node *np, | 433 | static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np) |
415 | struct at91_pmc *pmc) | ||
416 | { | 434 | { |
417 | of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91SAM9X5); | 435 | of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5); |
418 | } | 436 | } |
437 | CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral", | ||
438 | of_at91sam9x5_clk_periph_setup); | ||
439 | |||
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c index 18b60f4895a6..fb2e0b56d4b7 100644 --- a/drivers/clk/at91/clk-pll.c +++ b/drivers/clk/at91/clk-pll.c | |||
@@ -12,14 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/of_irq.h> | 16 | #include <linux/regmap.h> |
17 | #include <linux/io.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/wait.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/irq.h> | ||
23 | 17 | ||
24 | #include "pmc.h" | 18 | #include "pmc.h" |
25 | 19 | ||
@@ -58,9 +52,7 @@ struct clk_pll_layout { | |||
58 | 52 | ||
59 | struct clk_pll { | 53 | struct clk_pll { |
60 | struct clk_hw hw; | 54 | struct clk_hw hw; |
61 | struct at91_pmc *pmc; | 55 | struct regmap *regmap; |
62 | unsigned int irq; | ||
63 | wait_queue_head_t wait; | ||
64 | u8 id; | 56 | u8 id; |
65 | u8 div; | 57 | u8 div; |
66 | u8 range; | 58 | u8 range; |
@@ -69,20 +61,19 @@ struct clk_pll { | |||
69 | const struct clk_pll_characteristics *characteristics; | 61 | const struct clk_pll_characteristics *characteristics; |
70 | }; | 62 | }; |
71 | 63 | ||
72 | static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id) | 64 | static inline bool clk_pll_ready(struct regmap *regmap, int id) |
73 | { | 65 | { |
74 | struct clk_pll *pll = (struct clk_pll *)dev_id; | 66 | unsigned int status; |
75 | 67 | ||
76 | wake_up(&pll->wait); | 68 | regmap_read(regmap, AT91_PMC_SR, &status); |
77 | disable_irq_nosync(pll->irq); | ||
78 | 69 | ||
79 | return IRQ_HANDLED; | 70 | return status & PLL_STATUS_MASK(id) ? 1 : 0; |
80 | } | 71 | } |
81 | 72 | ||
82 | static int clk_pll_prepare(struct clk_hw *hw) | 73 | static int clk_pll_prepare(struct clk_hw *hw) |
83 | { | 74 | { |
84 | struct clk_pll *pll = to_clk_pll(hw); | 75 | struct clk_pll *pll = to_clk_pll(hw); |
85 | struct at91_pmc *pmc = pll->pmc; | 76 | struct regmap *regmap = pll->regmap; |
86 | const struct clk_pll_layout *layout = pll->layout; | 77 | const struct clk_pll_layout *layout = pll->layout; |
87 | const struct clk_pll_characteristics *characteristics = | 78 | const struct clk_pll_characteristics *characteristics = |
88 | pll->characteristics; | 79 | pll->characteristics; |
@@ -90,39 +81,34 @@ static int clk_pll_prepare(struct clk_hw *hw) | |||
90 | u32 mask = PLL_STATUS_MASK(id); | 81 | u32 mask = PLL_STATUS_MASK(id); |
91 | int offset = PLL_REG(id); | 82 | int offset = PLL_REG(id); |
92 | u8 out = 0; | 83 | u8 out = 0; |
93 | u32 pllr, icpr; | 84 | unsigned int pllr; |
85 | unsigned int status; | ||
94 | u8 div; | 86 | u8 div; |
95 | u16 mul; | 87 | u16 mul; |
96 | 88 | ||
97 | pllr = pmc_read(pmc, offset); | 89 | regmap_read(regmap, offset, &pllr); |
98 | div = PLL_DIV(pllr); | 90 | div = PLL_DIV(pllr); |
99 | mul = PLL_MUL(pllr, layout); | 91 | mul = PLL_MUL(pllr, layout); |
100 | 92 | ||
101 | if ((pmc_read(pmc, AT91_PMC_SR) & mask) && | 93 | regmap_read(regmap, AT91_PMC_SR, &status); |
94 | if ((status & mask) && | ||
102 | (div == pll->div && mul == pll->mul)) | 95 | (div == pll->div && mul == pll->mul)) |
103 | return 0; | 96 | return 0; |
104 | 97 | ||
105 | if (characteristics->out) | 98 | if (characteristics->out) |
106 | out = characteristics->out[pll->range]; | 99 | out = characteristics->out[pll->range]; |
107 | if (characteristics->icpll) { | ||
108 | icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id); | ||
109 | icpr |= (characteristics->icpll[pll->range] << | ||
110 | PLL_ICPR_SHIFT(id)); | ||
111 | pmc_write(pmc, AT91_PMC_PLLICPR, icpr); | ||
112 | } | ||
113 | 100 | ||
114 | pllr &= ~layout->pllr_mask; | 101 | if (characteristics->icpll) |
115 | pllr |= layout->pllr_mask & | 102 | regmap_update_bits(regmap, AT91_PMC_PLLICPR, PLL_ICPR_MASK(id), |
116 | (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | | 103 | characteristics->icpll[pll->range] << PLL_ICPR_SHIFT(id)); |
117 | (out << PLL_OUT_SHIFT) | | 104 | |
118 | ((pll->mul & layout->mul_mask) << layout->mul_shift)); | 105 | regmap_update_bits(regmap, offset, layout->pllr_mask, |
119 | pmc_write(pmc, offset, pllr); | 106 | pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | |
120 | 107 | (out << PLL_OUT_SHIFT) | | |
121 | while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) { | 108 | ((pll->mul & layout->mul_mask) << layout->mul_shift)); |
122 | enable_irq(pll->irq); | 109 | |
123 | wait_event(pll->wait, | 110 | while (!clk_pll_ready(regmap, pll->id)) |
124 | pmc_read(pmc, AT91_PMC_SR) & mask); | 111 | cpu_relax(); |
125 | } | ||
126 | 112 | ||
127 | return 0; | 113 | return 0; |
128 | } | 114 | } |
@@ -130,32 +116,35 @@ static int clk_pll_prepare(struct clk_hw *hw) | |||
130 | static int clk_pll_is_prepared(struct clk_hw *hw) | 116 | static int clk_pll_is_prepared(struct clk_hw *hw) |
131 | { | 117 | { |
132 | struct clk_pll *pll = to_clk_pll(hw); | 118 | struct clk_pll *pll = to_clk_pll(hw); |
133 | struct at91_pmc *pmc = pll->pmc; | ||
134 | 119 | ||
135 | return !!(pmc_read(pmc, AT91_PMC_SR) & | 120 | return clk_pll_ready(pll->regmap, pll->id); |
136 | PLL_STATUS_MASK(pll->id)); | ||
137 | } | 121 | } |
138 | 122 | ||
139 | static void clk_pll_unprepare(struct clk_hw *hw) | 123 | static void clk_pll_unprepare(struct clk_hw *hw) |
140 | { | 124 | { |
141 | struct clk_pll *pll = to_clk_pll(hw); | 125 | struct clk_pll *pll = to_clk_pll(hw); |
142 | struct at91_pmc *pmc = pll->pmc; | 126 | unsigned int mask = pll->layout->pllr_mask; |
143 | const struct clk_pll_layout *layout = pll->layout; | ||
144 | int offset = PLL_REG(pll->id); | ||
145 | u32 tmp = pmc_read(pmc, offset) & ~(layout->pllr_mask); | ||
146 | 127 | ||
147 | pmc_write(pmc, offset, tmp); | 128 | regmap_update_bits(pll->regmap, PLL_REG(pll->id), mask, ~mask); |
148 | } | 129 | } |
149 | 130 | ||
150 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | 131 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, |
151 | unsigned long parent_rate) | 132 | unsigned long parent_rate) |
152 | { | 133 | { |
153 | struct clk_pll *pll = to_clk_pll(hw); | 134 | struct clk_pll *pll = to_clk_pll(hw); |
135 | unsigned int pllr; | ||
136 | u16 mul; | ||
137 | u8 div; | ||
154 | 138 | ||
155 | if (!pll->div || !pll->mul) | 139 | regmap_read(pll->regmap, PLL_REG(pll->id), &pllr); |
140 | |||
141 | div = PLL_DIV(pllr); | ||
142 | mul = PLL_MUL(pllr, pll->layout); | ||
143 | |||
144 | if (!div || !mul) | ||
156 | return 0; | 145 | return 0; |
157 | 146 | ||
158 | return (parent_rate / pll->div) * (pll->mul + 1); | 147 | return (parent_rate / div) * (mul + 1); |
159 | } | 148 | } |
160 | 149 | ||
161 | static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, | 150 | static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, |
@@ -308,7 +297,7 @@ static const struct clk_ops pll_ops = { | |||
308 | }; | 297 | }; |
309 | 298 | ||
310 | static struct clk * __init | 299 | static struct clk * __init |
311 | at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, | 300 | at91_clk_register_pll(struct regmap *regmap, const char *name, |
312 | const char *parent_name, u8 id, | 301 | const char *parent_name, u8 id, |
313 | const struct clk_pll_layout *layout, | 302 | const struct clk_pll_layout *layout, |
314 | const struct clk_pll_characteristics *characteristics) | 303 | const struct clk_pll_characteristics *characteristics) |
@@ -316,9 +305,8 @@ at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, | |||
316 | struct clk_pll *pll; | 305 | struct clk_pll *pll; |
317 | struct clk *clk = NULL; | 306 | struct clk *clk = NULL; |
318 | struct clk_init_data init; | 307 | struct clk_init_data init; |
319 | int ret; | ||
320 | int offset = PLL_REG(id); | 308 | int offset = PLL_REG(id); |
321 | u32 tmp; | 309 | unsigned int pllr; |
322 | 310 | ||
323 | if (id > PLL_MAX_ID) | 311 | if (id > PLL_MAX_ID) |
324 | return ERR_PTR(-EINVAL); | 312 | return ERR_PTR(-EINVAL); |
@@ -337,23 +325,13 @@ at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, | |||
337 | pll->hw.init = &init; | 325 | pll->hw.init = &init; |
338 | pll->layout = layout; | 326 | pll->layout = layout; |
339 | pll->characteristics = characteristics; | 327 | pll->characteristics = characteristics; |
340 | pll->pmc = pmc; | 328 | pll->regmap = regmap; |
341 | pll->irq = irq; | 329 | regmap_read(regmap, offset, &pllr); |
342 | tmp = pmc_read(pmc, offset) & layout->pllr_mask; | 330 | pll->div = PLL_DIV(pllr); |
343 | pll->div = PLL_DIV(tmp); | 331 | pll->mul = PLL_MUL(pllr, layout); |
344 | pll->mul = PLL_MUL(tmp, layout); | ||
345 | init_waitqueue_head(&pll->wait); | ||
346 | irq_set_status_flags(pll->irq, IRQ_NOAUTOEN); | ||
347 | ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH, | ||
348 | id ? "clk-pllb" : "clk-plla", pll); | ||
349 | if (ret) { | ||
350 | kfree(pll); | ||
351 | return ERR_PTR(ret); | ||
352 | } | ||
353 | 332 | ||
354 | clk = clk_register(NULL, &pll->hw); | 333 | clk = clk_register(NULL, &pll->hw); |
355 | if (IS_ERR(clk)) { | 334 | if (IS_ERR(clk)) { |
356 | free_irq(pll->irq, pll); | ||
357 | kfree(pll); | 335 | kfree(pll); |
358 | } | 336 | } |
359 | 337 | ||
@@ -483,12 +461,12 @@ out_free_characteristics: | |||
483 | } | 461 | } |
484 | 462 | ||
485 | static void __init | 463 | static void __init |
486 | of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc, | 464 | of_at91_clk_pll_setup(struct device_node *np, |
487 | const struct clk_pll_layout *layout) | 465 | const struct clk_pll_layout *layout) |
488 | { | 466 | { |
489 | u32 id; | 467 | u32 id; |
490 | unsigned int irq; | ||
491 | struct clk *clk; | 468 | struct clk *clk; |
469 | struct regmap *regmap; | ||
492 | const char *parent_name; | 470 | const char *parent_name; |
493 | const char *name = np->name; | 471 | const char *name = np->name; |
494 | struct clk_pll_characteristics *characteristics; | 472 | struct clk_pll_characteristics *characteristics; |
@@ -500,15 +478,15 @@ of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc, | |||
500 | 478 | ||
501 | of_property_read_string(np, "clock-output-names", &name); | 479 | of_property_read_string(np, "clock-output-names", &name); |
502 | 480 | ||
503 | characteristics = of_at91_clk_pll_get_characteristics(np); | 481 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
504 | if (!characteristics) | 482 | if (IS_ERR(regmap)) |
505 | return; | 483 | return; |
506 | 484 | ||
507 | irq = irq_of_parse_and_map(np, 0); | 485 | characteristics = of_at91_clk_pll_get_characteristics(np); |
508 | if (!irq) | 486 | if (!characteristics) |
509 | return; | 487 | return; |
510 | 488 | ||
511 | clk = at91_clk_register_pll(pmc, irq, name, parent_name, id, layout, | 489 | clk = at91_clk_register_pll(regmap, name, parent_name, id, layout, |
512 | characteristics); | 490 | characteristics); |
513 | if (IS_ERR(clk)) | 491 | if (IS_ERR(clk)) |
514 | goto out_free_characteristics; | 492 | goto out_free_characteristics; |
@@ -520,26 +498,30 @@ out_free_characteristics: | |||
520 | kfree(characteristics); | 498 | kfree(characteristics); |
521 | } | 499 | } |
522 | 500 | ||
523 | void __init of_at91rm9200_clk_pll_setup(struct device_node *np, | 501 | static void __init of_at91rm9200_clk_pll_setup(struct device_node *np) |
524 | struct at91_pmc *pmc) | ||
525 | { | 502 | { |
526 | of_at91_clk_pll_setup(np, pmc, &at91rm9200_pll_layout); | 503 | of_at91_clk_pll_setup(np, &at91rm9200_pll_layout); |
527 | } | 504 | } |
505 | CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll", | ||
506 | of_at91rm9200_clk_pll_setup); | ||
528 | 507 | ||
529 | void __init of_at91sam9g45_clk_pll_setup(struct device_node *np, | 508 | static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np) |
530 | struct at91_pmc *pmc) | ||
531 | { | 509 | { |
532 | of_at91_clk_pll_setup(np, pmc, &at91sam9g45_pll_layout); | 510 | of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout); |
533 | } | 511 | } |
512 | CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll", | ||
513 | of_at91sam9g45_clk_pll_setup); | ||
534 | 514 | ||
535 | void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np, | 515 | static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np) |
536 | struct at91_pmc *pmc) | ||
537 | { | 516 | { |
538 | of_at91_clk_pll_setup(np, pmc, &at91sam9g20_pllb_layout); | 517 | of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout); |
539 | } | 518 | } |
519 | CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb", | ||
520 | of_at91sam9g20_clk_pllb_setup); | ||
540 | 521 | ||
541 | void __init of_sama5d3_clk_pll_setup(struct device_node *np, | 522 | static void __init of_sama5d3_clk_pll_setup(struct device_node *np) |
542 | struct at91_pmc *pmc) | ||
543 | { | 523 | { |
544 | of_at91_clk_pll_setup(np, pmc, &sama5d3_pll_layout); | 524 | of_at91_clk_pll_setup(np, &sama5d3_pll_layout); |
545 | } | 525 | } |
526 | CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll", | ||
527 | of_sama5d3_clk_pll_setup); | ||
diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c index ea226562bb40..2bed26481027 100644 --- a/drivers/clk/at91/clk-plldiv.c +++ b/drivers/clk/at91/clk-plldiv.c | |||
@@ -12,8 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/io.h> | 16 | #include <linux/regmap.h> |
17 | 17 | ||
18 | #include "pmc.h" | 18 | #include "pmc.h" |
19 | 19 | ||
@@ -21,16 +21,18 @@ | |||
21 | 21 | ||
22 | struct clk_plldiv { | 22 | struct clk_plldiv { |
23 | struct clk_hw hw; | 23 | struct clk_hw hw; |
24 | struct at91_pmc *pmc; | 24 | struct regmap *regmap; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw, | 27 | static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw, |
28 | unsigned long parent_rate) | 28 | unsigned long parent_rate) |
29 | { | 29 | { |
30 | struct clk_plldiv *plldiv = to_clk_plldiv(hw); | 30 | struct clk_plldiv *plldiv = to_clk_plldiv(hw); |
31 | struct at91_pmc *pmc = plldiv->pmc; | 31 | unsigned int mckr; |
32 | 32 | ||
33 | if (pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_PLLADIV2) | 33 | regmap_read(plldiv->regmap, AT91_PMC_MCKR, &mckr); |
34 | |||
35 | if (mckr & AT91_PMC_PLLADIV2) | ||
34 | return parent_rate / 2; | 36 | return parent_rate / 2; |
35 | 37 | ||
36 | return parent_rate; | 38 | return parent_rate; |
@@ -57,18 +59,12 @@ static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate, | |||
57 | unsigned long parent_rate) | 59 | unsigned long parent_rate) |
58 | { | 60 | { |
59 | struct clk_plldiv *plldiv = to_clk_plldiv(hw); | 61 | struct clk_plldiv *plldiv = to_clk_plldiv(hw); |
60 | struct at91_pmc *pmc = plldiv->pmc; | ||
61 | u32 tmp; | ||
62 | 62 | ||
63 | if (parent_rate != rate && (parent_rate / 2) != rate) | 63 | if ((parent_rate != rate) && (parent_rate / 2 != rate)) |
64 | return -EINVAL; | 64 | return -EINVAL; |
65 | 65 | ||
66 | pmc_lock(pmc); | 66 | regmap_update_bits(plldiv->regmap, AT91_PMC_MCKR, AT91_PMC_PLLADIV2, |
67 | tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_PLLADIV2; | 67 | parent_rate != rate ? AT91_PMC_PLLADIV2 : 0); |
68 | if ((parent_rate / 2) == rate) | ||
69 | tmp |= AT91_PMC_PLLADIV2; | ||
70 | pmc_write(pmc, AT91_PMC_MCKR, tmp); | ||
71 | pmc_unlock(pmc); | ||
72 | 68 | ||
73 | return 0; | 69 | return 0; |
74 | } | 70 | } |
@@ -80,7 +76,7 @@ static const struct clk_ops plldiv_ops = { | |||
80 | }; | 76 | }; |
81 | 77 | ||
82 | static struct clk * __init | 78 | static struct clk * __init |
83 | at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name, | 79 | at91_clk_register_plldiv(struct regmap *regmap, const char *name, |
84 | const char *parent_name) | 80 | const char *parent_name) |
85 | { | 81 | { |
86 | struct clk_plldiv *plldiv; | 82 | struct clk_plldiv *plldiv; |
@@ -98,7 +94,7 @@ at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name, | |||
98 | init.flags = CLK_SET_RATE_GATE; | 94 | init.flags = CLK_SET_RATE_GATE; |
99 | 95 | ||
100 | plldiv->hw.init = &init; | 96 | plldiv->hw.init = &init; |
101 | plldiv->pmc = pmc; | 97 | plldiv->regmap = regmap; |
102 | 98 | ||
103 | clk = clk_register(NULL, &plldiv->hw); | 99 | clk = clk_register(NULL, &plldiv->hw); |
104 | 100 | ||
@@ -109,27 +105,27 @@ at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name, | |||
109 | } | 105 | } |
110 | 106 | ||
111 | static void __init | 107 | static void __init |
112 | of_at91_clk_plldiv_setup(struct device_node *np, struct at91_pmc *pmc) | 108 | of_at91sam9x5_clk_plldiv_setup(struct device_node *np) |
113 | { | 109 | { |
114 | struct clk *clk; | 110 | struct clk *clk; |
115 | const char *parent_name; | 111 | const char *parent_name; |
116 | const char *name = np->name; | 112 | const char *name = np->name; |
113 | struct regmap *regmap; | ||
117 | 114 | ||
118 | parent_name = of_clk_get_parent_name(np, 0); | 115 | parent_name = of_clk_get_parent_name(np, 0); |
119 | 116 | ||
120 | of_property_read_string(np, "clock-output-names", &name); | 117 | of_property_read_string(np, "clock-output-names", &name); |
121 | 118 | ||
122 | clk = at91_clk_register_plldiv(pmc, name, parent_name); | 119 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
120 | if (IS_ERR(regmap)) | ||
121 | return; | ||
123 | 122 | ||
123 | clk = at91_clk_register_plldiv(regmap, name, parent_name); | ||
124 | if (IS_ERR(clk)) | 124 | if (IS_ERR(clk)) |
125 | return; | 125 | return; |
126 | 126 | ||
127 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 127 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
128 | return; | 128 | return; |
129 | } | 129 | } |
130 | 130 | CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv", | |
131 | void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np, | 131 | of_at91sam9x5_clk_plldiv_setup); |
132 | struct at91_pmc *pmc) | ||
133 | { | ||
134 | of_at91_clk_plldiv_setup(np, pmc); | ||
135 | } | ||
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 14b270b85fec..bc0be629671b 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c | |||
@@ -12,10 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/io.h> | 16 | #include <linux/regmap.h> |
17 | #include <linux/wait.h> | ||
18 | #include <linux/sched.h> | ||
19 | 17 | ||
20 | #include "pmc.h" | 18 | #include "pmc.h" |
21 | 19 | ||
@@ -24,6 +22,7 @@ | |||
24 | 22 | ||
25 | #define PROG_STATUS_MASK(id) (1 << ((id) + 8)) | 23 | #define PROG_STATUS_MASK(id) (1 << ((id) + 8)) |
26 | #define PROG_PRES_MASK 0x7 | 24 | #define PROG_PRES_MASK 0x7 |
25 | #define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK) | ||
27 | #define PROG_MAX_RM9200_CSS 3 | 26 | #define PROG_MAX_RM9200_CSS 3 |
28 | 27 | ||
29 | struct clk_programmable_layout { | 28 | struct clk_programmable_layout { |
@@ -34,7 +33,7 @@ struct clk_programmable_layout { | |||
34 | 33 | ||
35 | struct clk_programmable { | 34 | struct clk_programmable { |
36 | struct clk_hw hw; | 35 | struct clk_hw hw; |
37 | struct at91_pmc *pmc; | 36 | struct regmap *regmap; |
38 | u8 id; | 37 | u8 id; |
39 | const struct clk_programmable_layout *layout; | 38 | const struct clk_programmable_layout *layout; |
40 | }; | 39 | }; |
@@ -44,14 +43,12 @@ struct clk_programmable { | |||
44 | static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, | 43 | static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, |
45 | unsigned long parent_rate) | 44 | unsigned long parent_rate) |
46 | { | 45 | { |
47 | u32 pres; | ||
48 | struct clk_programmable *prog = to_clk_programmable(hw); | 46 | struct clk_programmable *prog = to_clk_programmable(hw); |
49 | struct at91_pmc *pmc = prog->pmc; | 47 | unsigned int pckr; |
50 | const struct clk_programmable_layout *layout = prog->layout; | 48 | |
49 | regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); | ||
51 | 50 | ||
52 | pres = (pmc_read(pmc, AT91_PMC_PCKR(prog->id)) >> layout->pres_shift) & | 51 | return parent_rate >> PROG_PRES(prog->layout, pckr); |
53 | PROG_PRES_MASK; | ||
54 | return parent_rate >> pres; | ||
55 | } | 52 | } |
56 | 53 | ||
57 | static int clk_programmable_determine_rate(struct clk_hw *hw, | 54 | static int clk_programmable_determine_rate(struct clk_hw *hw, |
@@ -101,36 +98,36 @@ static int clk_programmable_set_parent(struct clk_hw *hw, u8 index) | |||
101 | { | 98 | { |
102 | struct clk_programmable *prog = to_clk_programmable(hw); | 99 | struct clk_programmable *prog = to_clk_programmable(hw); |
103 | const struct clk_programmable_layout *layout = prog->layout; | 100 | const struct clk_programmable_layout *layout = prog->layout; |
104 | struct at91_pmc *pmc = prog->pmc; | 101 | unsigned int mask = layout->css_mask; |
105 | u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & ~layout->css_mask; | 102 | unsigned int pckr = 0; |
106 | 103 | ||
107 | if (layout->have_slck_mck) | 104 | if (layout->have_slck_mck) |
108 | tmp &= AT91_PMC_CSSMCK_MCK; | 105 | mask |= AT91_PMC_CSSMCK_MCK; |
109 | 106 | ||
110 | if (index > layout->css_mask) { | 107 | if (index > layout->css_mask) { |
111 | if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) { | 108 | if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck) |
112 | tmp |= AT91_PMC_CSSMCK_MCK; | ||
113 | return 0; | ||
114 | } else { | ||
115 | return -EINVAL; | 109 | return -EINVAL; |
116 | } | 110 | |
111 | pckr |= AT91_PMC_CSSMCK_MCK; | ||
117 | } | 112 | } |
118 | 113 | ||
119 | pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | index); | 114 | regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), mask, pckr); |
115 | |||
120 | return 0; | 116 | return 0; |
121 | } | 117 | } |
122 | 118 | ||
123 | static u8 clk_programmable_get_parent(struct clk_hw *hw) | 119 | static u8 clk_programmable_get_parent(struct clk_hw *hw) |
124 | { | 120 | { |
125 | u32 tmp; | ||
126 | u8 ret; | ||
127 | struct clk_programmable *prog = to_clk_programmable(hw); | 121 | struct clk_programmable *prog = to_clk_programmable(hw); |
128 | struct at91_pmc *pmc = prog->pmc; | ||
129 | const struct clk_programmable_layout *layout = prog->layout; | 122 | const struct clk_programmable_layout *layout = prog->layout; |
123 | unsigned int pckr; | ||
124 | u8 ret; | ||
125 | |||
126 | regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); | ||
127 | |||
128 | ret = pckr & layout->css_mask; | ||
130 | 129 | ||
131 | tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)); | 130 | if (layout->have_slck_mck && (pckr & AT91_PMC_CSSMCK_MCK) && !ret) |
132 | ret = tmp & layout->css_mask; | ||
133 | if (layout->have_slck_mck && (tmp & AT91_PMC_CSSMCK_MCK) && !ret) | ||
134 | ret = PROG_MAX_RM9200_CSS + 1; | 131 | ret = PROG_MAX_RM9200_CSS + 1; |
135 | 132 | ||
136 | return ret; | 133 | return ret; |
@@ -140,26 +137,27 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate, | |||
140 | unsigned long parent_rate) | 137 | unsigned long parent_rate) |
141 | { | 138 | { |
142 | struct clk_programmable *prog = to_clk_programmable(hw); | 139 | struct clk_programmable *prog = to_clk_programmable(hw); |
143 | struct at91_pmc *pmc = prog->pmc; | ||
144 | const struct clk_programmable_layout *layout = prog->layout; | 140 | const struct clk_programmable_layout *layout = prog->layout; |
145 | unsigned long div = parent_rate / rate; | 141 | unsigned long div = parent_rate / rate; |
142 | unsigned int pckr; | ||
146 | int shift = 0; | 143 | int shift = 0; |
147 | u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & | 144 | |
148 | ~(PROG_PRES_MASK << layout->pres_shift); | 145 | regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); |
149 | 146 | ||
150 | if (!div) | 147 | if (!div) |
151 | return -EINVAL; | 148 | return -EINVAL; |
152 | 149 | ||
153 | shift = fls(div) - 1; | 150 | shift = fls(div) - 1; |
154 | 151 | ||
155 | if (div != (1<<shift)) | 152 | if (div != (1 << shift)) |
156 | return -EINVAL; | 153 | return -EINVAL; |
157 | 154 | ||
158 | if (shift >= PROG_PRES_MASK) | 155 | if (shift >= PROG_PRES_MASK) |
159 | return -EINVAL; | 156 | return -EINVAL; |
160 | 157 | ||
161 | pmc_write(pmc, AT91_PMC_PCKR(prog->id), | 158 | regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), |
162 | tmp | (shift << layout->pres_shift)); | 159 | PROG_PRES_MASK << layout->pres_shift, |
160 | shift << layout->pres_shift); | ||
163 | 161 | ||
164 | return 0; | 162 | return 0; |
165 | } | 163 | } |
@@ -173,7 +171,7 @@ static const struct clk_ops programmable_ops = { | |||
173 | }; | 171 | }; |
174 | 172 | ||
175 | static struct clk * __init | 173 | static struct clk * __init |
176 | at91_clk_register_programmable(struct at91_pmc *pmc, | 174 | at91_clk_register_programmable(struct regmap *regmap, |
177 | const char *name, const char **parent_names, | 175 | const char *name, const char **parent_names, |
178 | u8 num_parents, u8 id, | 176 | u8 num_parents, u8 id, |
179 | const struct clk_programmable_layout *layout) | 177 | const struct clk_programmable_layout *layout) |
@@ -198,7 +196,7 @@ at91_clk_register_programmable(struct at91_pmc *pmc, | |||
198 | prog->id = id; | 196 | prog->id = id; |
199 | prog->layout = layout; | 197 | prog->layout = layout; |
200 | prog->hw.init = &init; | 198 | prog->hw.init = &init; |
201 | prog->pmc = pmc; | 199 | prog->regmap = regmap; |
202 | 200 | ||
203 | clk = clk_register(NULL, &prog->hw); | 201 | clk = clk_register(NULL, &prog->hw); |
204 | if (IS_ERR(clk)) | 202 | if (IS_ERR(clk)) |
@@ -226,7 +224,7 @@ static const struct clk_programmable_layout at91sam9x5_programmable_layout = { | |||
226 | }; | 224 | }; |
227 | 225 | ||
228 | static void __init | 226 | static void __init |
229 | of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, | 227 | of_at91_clk_prog_setup(struct device_node *np, |
230 | const struct clk_programmable_layout *layout) | 228 | const struct clk_programmable_layout *layout) |
231 | { | 229 | { |
232 | int num; | 230 | int num; |
@@ -236,6 +234,7 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, | |||
236 | const char *parent_names[PROG_SOURCE_MAX]; | 234 | const char *parent_names[PROG_SOURCE_MAX]; |
237 | const char *name; | 235 | const char *name; |
238 | struct device_node *progclknp; | 236 | struct device_node *progclknp; |
237 | struct regmap *regmap; | ||
239 | 238 | ||
240 | num_parents = of_clk_get_parent_count(np); | 239 | num_parents = of_clk_get_parent_count(np); |
241 | if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX) | 240 | if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX) |
@@ -247,6 +246,10 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, | |||
247 | if (!num || num > (PROG_ID_MAX + 1)) | 246 | if (!num || num > (PROG_ID_MAX + 1)) |
248 | return; | 247 | return; |
249 | 248 | ||
249 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
250 | if (IS_ERR(regmap)) | ||
251 | return; | ||
252 | |||
250 | for_each_child_of_node(np, progclknp) { | 253 | for_each_child_of_node(np, progclknp) { |
251 | if (of_property_read_u32(progclknp, "reg", &id)) | 254 | if (of_property_read_u32(progclknp, "reg", &id)) |
252 | continue; | 255 | continue; |
@@ -254,7 +257,7 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, | |||
254 | if (of_property_read_string(np, "clock-output-names", &name)) | 257 | if (of_property_read_string(np, "clock-output-names", &name)) |
255 | name = progclknp->name; | 258 | name = progclknp->name; |
256 | 259 | ||
257 | clk = at91_clk_register_programmable(pmc, name, | 260 | clk = at91_clk_register_programmable(regmap, name, |
258 | parent_names, num_parents, | 261 | parent_names, num_parents, |
259 | id, layout); | 262 | id, layout); |
260 | if (IS_ERR(clk)) | 263 | if (IS_ERR(clk)) |
@@ -265,20 +268,23 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, | |||
265 | } | 268 | } |
266 | 269 | ||
267 | 270 | ||
268 | void __init of_at91rm9200_clk_prog_setup(struct device_node *np, | 271 | static void __init of_at91rm9200_clk_prog_setup(struct device_node *np) |
269 | struct at91_pmc *pmc) | ||
270 | { | 272 | { |
271 | of_at91_clk_prog_setup(np, pmc, &at91rm9200_programmable_layout); | 273 | of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout); |
272 | } | 274 | } |
275 | CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable", | ||
276 | of_at91rm9200_clk_prog_setup); | ||
273 | 277 | ||
274 | void __init of_at91sam9g45_clk_prog_setup(struct device_node *np, | 278 | static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np) |
275 | struct at91_pmc *pmc) | ||
276 | { | 279 | { |
277 | of_at91_clk_prog_setup(np, pmc, &at91sam9g45_programmable_layout); | 280 | of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout); |
278 | } | 281 | } |
282 | CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable", | ||
283 | of_at91sam9g45_clk_prog_setup); | ||
279 | 284 | ||
280 | void __init of_at91sam9x5_clk_prog_setup(struct device_node *np, | 285 | static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np) |
281 | struct at91_pmc *pmc) | ||
282 | { | 286 | { |
283 | of_at91_clk_prog_setup(np, pmc, &at91sam9x5_programmable_layout); | 287 | of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout); |
284 | } | 288 | } |
289 | CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable", | ||
290 | of_at91sam9x5_clk_prog_setup); | ||
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 6f99a530ead6..911e941f8318 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c | |||
@@ -12,17 +12,11 @@ | |||
12 | 12 | ||
13 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
14 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
15 | #include <linux/slab.h> | ||
16 | #include <linux/clk/at91_pmc.h> | 15 | #include <linux/clk/at91_pmc.h> |
17 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
18 | #include <linux/of.h> | 17 | #include <linux/of.h> |
19 | #include <linux/of_address.h> | 18 | #include <linux/mfd/syscon.h> |
20 | #include <linux/of_irq.h> | 19 | #include <linux/regmap.h> |
21 | #include <linux/io.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/irq.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/wait.h> | ||
26 | 20 | ||
27 | #include "pmc.h" | 21 | #include "pmc.h" |
28 | #include "sckc.h" | 22 | #include "sckc.h" |
@@ -58,7 +52,7 @@ struct clk_slow_rc_osc { | |||
58 | 52 | ||
59 | struct clk_sam9260_slow { | 53 | struct clk_sam9260_slow { |
60 | struct clk_hw hw; | 54 | struct clk_hw hw; |
61 | struct at91_pmc *pmc; | 55 | struct regmap *regmap; |
62 | }; | 56 | }; |
63 | 57 | ||
64 | #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) | 58 | #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) |
@@ -388,8 +382,11 @@ void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, | |||
388 | static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) | 382 | static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) |
389 | { | 383 | { |
390 | struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); | 384 | struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); |
385 | unsigned int status; | ||
391 | 386 | ||
392 | return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL); | 387 | regmap_read(slowck->regmap, AT91_PMC_SR, &status); |
388 | |||
389 | return status & AT91_PMC_OSCSEL ? 1 : 0; | ||
393 | } | 390 | } |
394 | 391 | ||
395 | static const struct clk_ops sam9260_slow_ops = { | 392 | static const struct clk_ops sam9260_slow_ops = { |
@@ -397,7 +394,7 @@ static const struct clk_ops sam9260_slow_ops = { | |||
397 | }; | 394 | }; |
398 | 395 | ||
399 | static struct clk * __init | 396 | static struct clk * __init |
400 | at91_clk_register_sam9260_slow(struct at91_pmc *pmc, | 397 | at91_clk_register_sam9260_slow(struct regmap *regmap, |
401 | const char *name, | 398 | const char *name, |
402 | const char **parent_names, | 399 | const char **parent_names, |
403 | int num_parents) | 400 | int num_parents) |
@@ -406,7 +403,7 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, | |||
406 | struct clk *clk = NULL; | 403 | struct clk *clk = NULL; |
407 | struct clk_init_data init; | 404 | struct clk_init_data init; |
408 | 405 | ||
409 | if (!pmc || !name) | 406 | if (!name) |
410 | return ERR_PTR(-EINVAL); | 407 | return ERR_PTR(-EINVAL); |
411 | 408 | ||
412 | if (!parent_names || !num_parents) | 409 | if (!parent_names || !num_parents) |
@@ -423,7 +420,7 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, | |||
423 | init.flags = 0; | 420 | init.flags = 0; |
424 | 421 | ||
425 | slowck->hw.init = &init; | 422 | slowck->hw.init = &init; |
426 | slowck->pmc = pmc; | 423 | slowck->regmap = regmap; |
427 | 424 | ||
428 | clk = clk_register(NULL, &slowck->hw); | 425 | clk = clk_register(NULL, &slowck->hw); |
429 | if (IS_ERR(clk)) | 426 | if (IS_ERR(clk)) |
@@ -432,26 +429,32 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, | |||
432 | return clk; | 429 | return clk; |
433 | } | 430 | } |
434 | 431 | ||
435 | void __init of_at91sam9260_clk_slow_setup(struct device_node *np, | 432 | static void __init of_at91sam9260_clk_slow_setup(struct device_node *np) |
436 | struct at91_pmc *pmc) | ||
437 | { | 433 | { |
438 | struct clk *clk; | 434 | struct clk *clk; |
439 | const char *parent_names[2]; | 435 | const char *parent_names[2]; |
440 | int num_parents; | 436 | int num_parents; |
441 | const char *name = np->name; | 437 | const char *name = np->name; |
438 | struct regmap *regmap; | ||
442 | 439 | ||
443 | num_parents = of_clk_get_parent_count(np); | 440 | num_parents = of_clk_get_parent_count(np); |
444 | if (num_parents != 2) | 441 | if (num_parents != 2) |
445 | return; | 442 | return; |
446 | 443 | ||
447 | of_clk_parent_fill(np, parent_names, num_parents); | 444 | of_clk_parent_fill(np, parent_names, num_parents); |
445 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
446 | if (IS_ERR(regmap)) | ||
447 | return; | ||
448 | 448 | ||
449 | of_property_read_string(np, "clock-output-names", &name); | 449 | of_property_read_string(np, "clock-output-names", &name); |
450 | 450 | ||
451 | clk = at91_clk_register_sam9260_slow(pmc, name, parent_names, | 451 | clk = at91_clk_register_sam9260_slow(regmap, name, parent_names, |
452 | num_parents); | 452 | num_parents); |
453 | if (IS_ERR(clk)) | 453 | if (IS_ERR(clk)) |
454 | return; | 454 | return; |
455 | 455 | ||
456 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 456 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
457 | } | 457 | } |
458 | |||
459 | CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow", | ||
460 | of_at91sam9260_clk_slow_setup); | ||
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c index a7f8501cfa05..e6948a52005a 100644 --- a/drivers/clk/at91/clk-smd.c +++ b/drivers/clk/at91/clk-smd.c | |||
@@ -12,8 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/io.h> | 16 | #include <linux/regmap.h> |
17 | 17 | ||
18 | #include "pmc.h" | 18 | #include "pmc.h" |
19 | 19 | ||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | struct at91sam9x5_clk_smd { | 25 | struct at91sam9x5_clk_smd { |
26 | struct clk_hw hw; | 26 | struct clk_hw hw; |
27 | struct at91_pmc *pmc; | 27 | struct regmap *regmap; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | #define to_at91sam9x5_clk_smd(hw) \ | 30 | #define to_at91sam9x5_clk_smd(hw) \ |
@@ -33,13 +33,13 @@ struct at91sam9x5_clk_smd { | |||
33 | static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw, | 33 | static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw, |
34 | unsigned long parent_rate) | 34 | unsigned long parent_rate) |
35 | { | 35 | { |
36 | u32 tmp; | ||
37 | u8 smddiv; | ||
38 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | 36 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); |
39 | struct at91_pmc *pmc = smd->pmc; | 37 | unsigned int smdr; |
38 | u8 smddiv; | ||
39 | |||
40 | regmap_read(smd->regmap, AT91_PMC_SMD, &smdr); | ||
41 | smddiv = (smdr & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT; | ||
40 | 42 | ||
41 | tmp = pmc_read(pmc, AT91_PMC_SMD); | ||
42 | smddiv = (tmp & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT; | ||
43 | return parent_rate / (smddiv + 1); | 43 | return parent_rate / (smddiv + 1); |
44 | } | 44 | } |
45 | 45 | ||
@@ -67,40 +67,38 @@ static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate, | |||
67 | 67 | ||
68 | static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index) | 68 | static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index) |
69 | { | 69 | { |
70 | u32 tmp; | ||
71 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | 70 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); |
72 | struct at91_pmc *pmc = smd->pmc; | ||
73 | 71 | ||
74 | if (index > 1) | 72 | if (index > 1) |
75 | return -EINVAL; | 73 | return -EINVAL; |
76 | tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMDS; | 74 | |
77 | if (index) | 75 | regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMDS, |
78 | tmp |= AT91_PMC_SMDS; | 76 | index ? AT91_PMC_SMDS : 0); |
79 | pmc_write(pmc, AT91_PMC_SMD, tmp); | 77 | |
80 | return 0; | 78 | return 0; |
81 | } | 79 | } |
82 | 80 | ||
83 | static u8 at91sam9x5_clk_smd_get_parent(struct clk_hw *hw) | 81 | static u8 at91sam9x5_clk_smd_get_parent(struct clk_hw *hw) |
84 | { | 82 | { |
85 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | 83 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); |
86 | struct at91_pmc *pmc = smd->pmc; | 84 | unsigned int smdr; |
87 | 85 | ||
88 | return pmc_read(pmc, AT91_PMC_SMD) & AT91_PMC_SMDS; | 86 | regmap_read(smd->regmap, AT91_PMC_SMD, &smdr); |
87 | |||
88 | return smdr & AT91_PMC_SMDS; | ||
89 | } | 89 | } |
90 | 90 | ||
91 | static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate, | 91 | static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate, |
92 | unsigned long parent_rate) | 92 | unsigned long parent_rate) |
93 | { | 93 | { |
94 | u32 tmp; | ||
95 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | 94 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); |
96 | struct at91_pmc *pmc = smd->pmc; | ||
97 | unsigned long div = parent_rate / rate; | 95 | unsigned long div = parent_rate / rate; |
98 | 96 | ||
99 | if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1)) | 97 | if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1)) |
100 | return -EINVAL; | 98 | return -EINVAL; |
101 | tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMD_DIV; | 99 | |
102 | tmp |= (div - 1) << SMD_DIV_SHIFT; | 100 | regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMD_DIV, |
103 | pmc_write(pmc, AT91_PMC_SMD, tmp); | 101 | (div - 1) << SMD_DIV_SHIFT); |
104 | 102 | ||
105 | return 0; | 103 | return 0; |
106 | } | 104 | } |
@@ -114,7 +112,7 @@ static const struct clk_ops at91sam9x5_smd_ops = { | |||
114 | }; | 112 | }; |
115 | 113 | ||
116 | static struct clk * __init | 114 | static struct clk * __init |
117 | at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name, | 115 | at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name, |
118 | const char **parent_names, u8 num_parents) | 116 | const char **parent_names, u8 num_parents) |
119 | { | 117 | { |
120 | struct at91sam9x5_clk_smd *smd; | 118 | struct at91sam9x5_clk_smd *smd; |
@@ -132,7 +130,7 @@ at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name, | |||
132 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; | 130 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; |
133 | 131 | ||
134 | smd->hw.init = &init; | 132 | smd->hw.init = &init; |
135 | smd->pmc = pmc; | 133 | smd->regmap = regmap; |
136 | 134 | ||
137 | clk = clk_register(NULL, &smd->hw); | 135 | clk = clk_register(NULL, &smd->hw); |
138 | if (IS_ERR(clk)) | 136 | if (IS_ERR(clk)) |
@@ -141,13 +139,13 @@ at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name, | |||
141 | return clk; | 139 | return clk; |
142 | } | 140 | } |
143 | 141 | ||
144 | void __init of_at91sam9x5_clk_smd_setup(struct device_node *np, | 142 | static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np) |
145 | struct at91_pmc *pmc) | ||
146 | { | 143 | { |
147 | struct clk *clk; | 144 | struct clk *clk; |
148 | int num_parents; | 145 | int num_parents; |
149 | const char *parent_names[SMD_SOURCE_MAX]; | 146 | const char *parent_names[SMD_SOURCE_MAX]; |
150 | const char *name = np->name; | 147 | const char *name = np->name; |
148 | struct regmap *regmap; | ||
151 | 149 | ||
152 | num_parents = of_clk_get_parent_count(np); | 150 | num_parents = of_clk_get_parent_count(np); |
153 | if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX) | 151 | if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX) |
@@ -157,10 +155,16 @@ void __init of_at91sam9x5_clk_smd_setup(struct device_node *np, | |||
157 | 155 | ||
158 | of_property_read_string(np, "clock-output-names", &name); | 156 | of_property_read_string(np, "clock-output-names", &name); |
159 | 157 | ||
160 | clk = at91sam9x5_clk_register_smd(pmc, name, parent_names, | 158 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
159 | if (IS_ERR(regmap)) | ||
160 | return; | ||
161 | |||
162 | clk = at91sam9x5_clk_register_smd(regmap, name, parent_names, | ||
161 | num_parents); | 163 | num_parents); |
162 | if (IS_ERR(clk)) | 164 | if (IS_ERR(clk)) |
163 | return; | 165 | return; |
164 | 166 | ||
165 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 167 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
166 | } | 168 | } |
169 | CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd", | ||
170 | of_at91sam9x5_clk_smd_setup); | ||
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c index 3f5314344286..8f35d8172909 100644 --- a/drivers/clk/at91/clk-system.c +++ b/drivers/clk/at91/clk-system.c | |||
@@ -12,13 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/io.h> | 16 | #include <linux/regmap.h> |
17 | #include <linux/irq.h> | ||
18 | #include <linux/of_irq.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/wait.h> | ||
21 | #include <linux/sched.h> | ||
22 | 17 | ||
23 | #include "pmc.h" | 18 | #include "pmc.h" |
24 | 19 | ||
@@ -29,9 +24,7 @@ | |||
29 | #define to_clk_system(hw) container_of(hw, struct clk_system, hw) | 24 | #define to_clk_system(hw) container_of(hw, struct clk_system, hw) |
30 | struct clk_system { | 25 | struct clk_system { |
31 | struct clk_hw hw; | 26 | struct clk_hw hw; |
32 | struct at91_pmc *pmc; | 27 | struct regmap *regmap; |
33 | unsigned int irq; | ||
34 | wait_queue_head_t wait; | ||
35 | u8 id; | 28 | u8 id; |
36 | }; | 29 | }; |
37 | 30 | ||
@@ -39,58 +32,54 @@ static inline int is_pck(int id) | |||
39 | { | 32 | { |
40 | return (id >= 8) && (id <= 15); | 33 | return (id >= 8) && (id <= 15); |
41 | } | 34 | } |
42 | static irqreturn_t clk_system_irq_handler(int irq, void *dev_id) | 35 | |
36 | static inline bool clk_system_ready(struct regmap *regmap, int id) | ||
43 | { | 37 | { |
44 | struct clk_system *sys = (struct clk_system *)dev_id; | 38 | unsigned int status; |
45 | 39 | ||
46 | wake_up(&sys->wait); | 40 | regmap_read(regmap, AT91_PMC_SR, &status); |
47 | disable_irq_nosync(sys->irq); | ||
48 | 41 | ||
49 | return IRQ_HANDLED; | 42 | return status & (1 << id) ? 1 : 0; |
50 | } | 43 | } |
51 | 44 | ||
52 | static int clk_system_prepare(struct clk_hw *hw) | 45 | static int clk_system_prepare(struct clk_hw *hw) |
53 | { | 46 | { |
54 | struct clk_system *sys = to_clk_system(hw); | 47 | struct clk_system *sys = to_clk_system(hw); |
55 | struct at91_pmc *pmc = sys->pmc; | ||
56 | u32 mask = 1 << sys->id; | ||
57 | 48 | ||
58 | pmc_write(pmc, AT91_PMC_SCER, mask); | 49 | regmap_write(sys->regmap, AT91_PMC_SCER, 1 << sys->id); |
59 | 50 | ||
60 | if (!is_pck(sys->id)) | 51 | if (!is_pck(sys->id)) |
61 | return 0; | 52 | return 0; |
62 | 53 | ||
63 | while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) { | 54 | while (!clk_system_ready(sys->regmap, sys->id)) |
64 | if (sys->irq) { | 55 | cpu_relax(); |
65 | enable_irq(sys->irq); | 56 | |
66 | wait_event(sys->wait, | ||
67 | pmc_read(pmc, AT91_PMC_SR) & mask); | ||
68 | } else | ||
69 | cpu_relax(); | ||
70 | } | ||
71 | return 0; | 57 | return 0; |
72 | } | 58 | } |
73 | 59 | ||
74 | static void clk_system_unprepare(struct clk_hw *hw) | 60 | static void clk_system_unprepare(struct clk_hw *hw) |
75 | { | 61 | { |
76 | struct clk_system *sys = to_clk_system(hw); | 62 | struct clk_system *sys = to_clk_system(hw); |
77 | struct at91_pmc *pmc = sys->pmc; | ||
78 | 63 | ||
79 | pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id); | 64 | regmap_write(sys->regmap, AT91_PMC_SCDR, 1 << sys->id); |
80 | } | 65 | } |
81 | 66 | ||
82 | static int clk_system_is_prepared(struct clk_hw *hw) | 67 | static int clk_system_is_prepared(struct clk_hw *hw) |
83 | { | 68 | { |
84 | struct clk_system *sys = to_clk_system(hw); | 69 | struct clk_system *sys = to_clk_system(hw); |
85 | struct at91_pmc *pmc = sys->pmc; | 70 | unsigned int status; |
71 | |||
72 | regmap_read(sys->regmap, AT91_PMC_SCSR, &status); | ||
86 | 73 | ||
87 | if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id))) | 74 | if (!(status & (1 << sys->id))) |
88 | return 0; | 75 | return 0; |
89 | 76 | ||
90 | if (!is_pck(sys->id)) | 77 | if (!is_pck(sys->id)) |
91 | return 1; | 78 | return 1; |
92 | 79 | ||
93 | return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id)); | 80 | regmap_read(sys->regmap, AT91_PMC_SR, &status); |
81 | |||
82 | return status & (1 << sys->id) ? 1 : 0; | ||
94 | } | 83 | } |
95 | 84 | ||
96 | static const struct clk_ops system_ops = { | 85 | static const struct clk_ops system_ops = { |
@@ -100,13 +89,12 @@ static const struct clk_ops system_ops = { | |||
100 | }; | 89 | }; |
101 | 90 | ||
102 | static struct clk * __init | 91 | static struct clk * __init |
103 | at91_clk_register_system(struct at91_pmc *pmc, const char *name, | 92 | at91_clk_register_system(struct regmap *regmap, const char *name, |
104 | const char *parent_name, u8 id, int irq) | 93 | const char *parent_name, u8 id) |
105 | { | 94 | { |
106 | struct clk_system *sys; | 95 | struct clk_system *sys; |
107 | struct clk *clk = NULL; | 96 | struct clk *clk = NULL; |
108 | struct clk_init_data init; | 97 | struct clk_init_data init; |
109 | int ret; | ||
110 | 98 | ||
111 | if (!parent_name || id > SYSTEM_MAX_ID) | 99 | if (!parent_name || id > SYSTEM_MAX_ID) |
112 | return ERR_PTR(-EINVAL); | 100 | return ERR_PTR(-EINVAL); |
@@ -123,44 +111,33 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name, | |||
123 | 111 | ||
124 | sys->id = id; | 112 | sys->id = id; |
125 | sys->hw.init = &init; | 113 | sys->hw.init = &init; |
126 | sys->pmc = pmc; | 114 | sys->regmap = regmap; |
127 | sys->irq = irq; | ||
128 | if (irq) { | ||
129 | init_waitqueue_head(&sys->wait); | ||
130 | irq_set_status_flags(sys->irq, IRQ_NOAUTOEN); | ||
131 | ret = request_irq(sys->irq, clk_system_irq_handler, | ||
132 | IRQF_TRIGGER_HIGH, name, sys); | ||
133 | if (ret) { | ||
134 | kfree(sys); | ||
135 | return ERR_PTR(ret); | ||
136 | } | ||
137 | } | ||
138 | 115 | ||
139 | clk = clk_register(NULL, &sys->hw); | 116 | clk = clk_register(NULL, &sys->hw); |
140 | if (IS_ERR(clk)) { | 117 | if (IS_ERR(clk)) |
141 | if (irq) | ||
142 | free_irq(sys->irq, sys); | ||
143 | kfree(sys); | 118 | kfree(sys); |
144 | } | ||
145 | 119 | ||
146 | return clk; | 120 | return clk; |
147 | } | 121 | } |
148 | 122 | ||
149 | static void __init | 123 | static void __init of_at91rm9200_clk_sys_setup(struct device_node *np) |
150 | of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc) | ||
151 | { | 124 | { |
152 | int num; | 125 | int num; |
153 | int irq = 0; | ||
154 | u32 id; | 126 | u32 id; |
155 | struct clk *clk; | 127 | struct clk *clk; |
156 | const char *name; | 128 | const char *name; |
157 | struct device_node *sysclknp; | 129 | struct device_node *sysclknp; |
158 | const char *parent_name; | 130 | const char *parent_name; |
131 | struct regmap *regmap; | ||
159 | 132 | ||
160 | num = of_get_child_count(np); | 133 | num = of_get_child_count(np); |
161 | if (num > (SYSTEM_MAX_ID + 1)) | 134 | if (num > (SYSTEM_MAX_ID + 1)) |
162 | return; | 135 | return; |
163 | 136 | ||
137 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
138 | if (IS_ERR(regmap)) | ||
139 | return; | ||
140 | |||
164 | for_each_child_of_node(np, sysclknp) { | 141 | for_each_child_of_node(np, sysclknp) { |
165 | if (of_property_read_u32(sysclknp, "reg", &id)) | 142 | if (of_property_read_u32(sysclknp, "reg", &id)) |
166 | continue; | 143 | continue; |
@@ -168,21 +145,14 @@ of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc) | |||
168 | if (of_property_read_string(np, "clock-output-names", &name)) | 145 | if (of_property_read_string(np, "clock-output-names", &name)) |
169 | name = sysclknp->name; | 146 | name = sysclknp->name; |
170 | 147 | ||
171 | if (is_pck(id)) | ||
172 | irq = irq_of_parse_and_map(sysclknp, 0); | ||
173 | |||
174 | parent_name = of_clk_get_parent_name(sysclknp, 0); | 148 | parent_name = of_clk_get_parent_name(sysclknp, 0); |
175 | 149 | ||
176 | clk = at91_clk_register_system(pmc, name, parent_name, id, irq); | 150 | clk = at91_clk_register_system(regmap, name, parent_name, id); |
177 | if (IS_ERR(clk)) | 151 | if (IS_ERR(clk)) |
178 | continue; | 152 | continue; |
179 | 153 | ||
180 | of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk); | 154 | of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk); |
181 | } | 155 | } |
182 | } | 156 | } |
183 | 157 | CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system", | |
184 | void __init of_at91rm9200_clk_sys_setup(struct device_node *np, | 158 | of_at91rm9200_clk_sys_setup); |
185 | struct at91_pmc *pmc) | ||
186 | { | ||
187 | of_at91_clk_sys_setup(np, pmc); | ||
188 | } | ||
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 8ab8502778a2..650ca45892c0 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c | |||
@@ -12,8 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/io.h> | 16 | #include <linux/regmap.h> |
17 | 17 | ||
18 | #include "pmc.h" | 18 | #include "pmc.h" |
19 | 19 | ||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | struct at91sam9x5_clk_usb { | 28 | struct at91sam9x5_clk_usb { |
29 | struct clk_hw hw; | 29 | struct clk_hw hw; |
30 | struct at91_pmc *pmc; | 30 | struct regmap *regmap; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #define to_at91sam9x5_clk_usb(hw) \ | 33 | #define to_at91sam9x5_clk_usb(hw) \ |
@@ -35,7 +35,7 @@ struct at91sam9x5_clk_usb { | |||
35 | 35 | ||
36 | struct at91rm9200_clk_usb { | 36 | struct at91rm9200_clk_usb { |
37 | struct clk_hw hw; | 37 | struct clk_hw hw; |
38 | struct at91_pmc *pmc; | 38 | struct regmap *regmap; |
39 | u32 divisors[4]; | 39 | u32 divisors[4]; |
40 | }; | 40 | }; |
41 | 41 | ||
@@ -45,13 +45,12 @@ struct at91rm9200_clk_usb { | |||
45 | static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw, | 45 | static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw, |
46 | unsigned long parent_rate) | 46 | unsigned long parent_rate) |
47 | { | 47 | { |
48 | u32 tmp; | ||
49 | u8 usbdiv; | ||
50 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 48 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
51 | struct at91_pmc *pmc = usb->pmc; | 49 | unsigned int usbr; |
50 | u8 usbdiv; | ||
52 | 51 | ||
53 | tmp = pmc_read(pmc, AT91_PMC_USB); | 52 | regmap_read(usb->regmap, AT91_PMC_USB, &usbr); |
54 | usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; | 53 | usbdiv = (usbr & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; |
55 | 54 | ||
56 | return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1)); | 55 | return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1)); |
57 | } | 56 | } |
@@ -109,33 +108,31 @@ static int at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw, | |||
109 | 108 | ||
110 | static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) | 109 | static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) |
111 | { | 110 | { |
112 | u32 tmp; | ||
113 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 111 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
114 | struct at91_pmc *pmc = usb->pmc; | ||
115 | 112 | ||
116 | if (index > 1) | 113 | if (index > 1) |
117 | return -EINVAL; | 114 | return -EINVAL; |
118 | tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS; | 115 | |
119 | if (index) | 116 | regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, |
120 | tmp |= AT91_PMC_USBS; | 117 | index ? AT91_PMC_USBS : 0); |
121 | pmc_write(pmc, AT91_PMC_USB, tmp); | 118 | |
122 | return 0; | 119 | return 0; |
123 | } | 120 | } |
124 | 121 | ||
125 | static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) | 122 | static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) |
126 | { | 123 | { |
127 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 124 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
128 | struct at91_pmc *pmc = usb->pmc; | 125 | unsigned int usbr; |
129 | 126 | ||
130 | return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS; | 127 | regmap_read(usb->regmap, AT91_PMC_USB, &usbr); |
128 | |||
129 | return usbr & AT91_PMC_USBS; | ||
131 | } | 130 | } |
132 | 131 | ||
133 | static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | 132 | static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, |
134 | unsigned long parent_rate) | 133 | unsigned long parent_rate) |
135 | { | 134 | { |
136 | u32 tmp; | ||
137 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 135 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
138 | struct at91_pmc *pmc = usb->pmc; | ||
139 | unsigned long div; | 136 | unsigned long div; |
140 | 137 | ||
141 | if (!rate) | 138 | if (!rate) |
@@ -145,9 +142,8 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | |||
145 | if (div > SAM9X5_USB_MAX_DIV + 1 || !div) | 142 | if (div > SAM9X5_USB_MAX_DIV + 1 || !div) |
146 | return -EINVAL; | 143 | return -EINVAL; |
147 | 144 | ||
148 | tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; | 145 | regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_OHCIUSBDIV, |
149 | tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT; | 146 | (div - 1) << SAM9X5_USB_DIV_SHIFT); |
150 | pmc_write(pmc, AT91_PMC_USB, tmp); | ||
151 | 147 | ||
152 | return 0; | 148 | return 0; |
153 | } | 149 | } |
@@ -163,28 +159,28 @@ static const struct clk_ops at91sam9x5_usb_ops = { | |||
163 | static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) | 159 | static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) |
164 | { | 160 | { |
165 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 161 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
166 | struct at91_pmc *pmc = usb->pmc; | ||
167 | 162 | ||
168 | pmc_write(pmc, AT91_PMC_USB, | 163 | regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, |
169 | pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS); | 164 | AT91_PMC_USBS); |
165 | |||
170 | return 0; | 166 | return 0; |
171 | } | 167 | } |
172 | 168 | ||
173 | static void at91sam9n12_clk_usb_disable(struct clk_hw *hw) | 169 | static void at91sam9n12_clk_usb_disable(struct clk_hw *hw) |
174 | { | 170 | { |
175 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 171 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
176 | struct at91_pmc *pmc = usb->pmc; | ||
177 | 172 | ||
178 | pmc_write(pmc, AT91_PMC_USB, | 173 | regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, 0); |
179 | pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS); | ||
180 | } | 174 | } |
181 | 175 | ||
182 | static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw) | 176 | static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw) |
183 | { | 177 | { |
184 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | 178 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); |
185 | struct at91_pmc *pmc = usb->pmc; | 179 | unsigned int usbr; |
186 | 180 | ||
187 | return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS); | 181 | regmap_read(usb->regmap, AT91_PMC_USB, &usbr); |
182 | |||
183 | return usbr & AT91_PMC_USBS; | ||
188 | } | 184 | } |
189 | 185 | ||
190 | static const struct clk_ops at91sam9n12_usb_ops = { | 186 | static const struct clk_ops at91sam9n12_usb_ops = { |
@@ -197,7 +193,7 @@ static const struct clk_ops at91sam9n12_usb_ops = { | |||
197 | }; | 193 | }; |
198 | 194 | ||
199 | static struct clk * __init | 195 | static struct clk * __init |
200 | at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, | 196 | at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, |
201 | const char **parent_names, u8 num_parents) | 197 | const char **parent_names, u8 num_parents) |
202 | { | 198 | { |
203 | struct at91sam9x5_clk_usb *usb; | 199 | struct at91sam9x5_clk_usb *usb; |
@@ -216,7 +212,7 @@ at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, | |||
216 | CLK_SET_RATE_PARENT; | 212 | CLK_SET_RATE_PARENT; |
217 | 213 | ||
218 | usb->hw.init = &init; | 214 | usb->hw.init = &init; |
219 | usb->pmc = pmc; | 215 | usb->regmap = regmap; |
220 | 216 | ||
221 | clk = clk_register(NULL, &usb->hw); | 217 | clk = clk_register(NULL, &usb->hw); |
222 | if (IS_ERR(clk)) | 218 | if (IS_ERR(clk)) |
@@ -226,7 +222,7 @@ at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, | |||
226 | } | 222 | } |
227 | 223 | ||
228 | static struct clk * __init | 224 | static struct clk * __init |
229 | at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name, | 225 | at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, |
230 | const char *parent_name) | 226 | const char *parent_name) |
231 | { | 227 | { |
232 | struct at91sam9x5_clk_usb *usb; | 228 | struct at91sam9x5_clk_usb *usb; |
@@ -244,7 +240,7 @@ at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name, | |||
244 | init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; | 240 | init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; |
245 | 241 | ||
246 | usb->hw.init = &init; | 242 | usb->hw.init = &init; |
247 | usb->pmc = pmc; | 243 | usb->regmap = regmap; |
248 | 244 | ||
249 | clk = clk_register(NULL, &usb->hw); | 245 | clk = clk_register(NULL, &usb->hw); |
250 | if (IS_ERR(clk)) | 246 | if (IS_ERR(clk)) |
@@ -257,12 +253,12 @@ static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw, | |||
257 | unsigned long parent_rate) | 253 | unsigned long parent_rate) |
258 | { | 254 | { |
259 | struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); | 255 | struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); |
260 | struct at91_pmc *pmc = usb->pmc; | 256 | unsigned int pllbr; |
261 | u32 tmp; | ||
262 | u8 usbdiv; | 257 | u8 usbdiv; |
263 | 258 | ||
264 | tmp = pmc_read(pmc, AT91_CKGR_PLLBR); | 259 | regmap_read(usb->regmap, AT91_CKGR_PLLBR, &pllbr); |
265 | usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT; | 260 | |
261 | usbdiv = (pllbr & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT; | ||
266 | if (usb->divisors[usbdiv]) | 262 | if (usb->divisors[usbdiv]) |
267 | return parent_rate / usb->divisors[usbdiv]; | 263 | return parent_rate / usb->divisors[usbdiv]; |
268 | 264 | ||
@@ -310,10 +306,8 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, | |||
310 | static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | 306 | static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, |
311 | unsigned long parent_rate) | 307 | unsigned long parent_rate) |
312 | { | 308 | { |
313 | u32 tmp; | ||
314 | int i; | 309 | int i; |
315 | struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); | 310 | struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); |
316 | struct at91_pmc *pmc = usb->pmc; | ||
317 | unsigned long div; | 311 | unsigned long div; |
318 | 312 | ||
319 | if (!rate) | 313 | if (!rate) |
@@ -323,10 +317,10 @@ static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | |||
323 | 317 | ||
324 | for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { | 318 | for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { |
325 | if (usb->divisors[i] == div) { | 319 | if (usb->divisors[i] == div) { |
326 | tmp = pmc_read(pmc, AT91_CKGR_PLLBR) & | 320 | regmap_update_bits(usb->regmap, AT91_CKGR_PLLBR, |
327 | ~AT91_PMC_USBDIV; | 321 | AT91_PMC_USBDIV, |
328 | tmp |= i << RM9200_USB_DIV_SHIFT; | 322 | i << RM9200_USB_DIV_SHIFT); |
329 | pmc_write(pmc, AT91_CKGR_PLLBR, tmp); | 323 | |
330 | return 0; | 324 | return 0; |
331 | } | 325 | } |
332 | } | 326 | } |
@@ -341,7 +335,7 @@ static const struct clk_ops at91rm9200_usb_ops = { | |||
341 | }; | 335 | }; |
342 | 336 | ||
343 | static struct clk * __init | 337 | static struct clk * __init |
344 | at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, | 338 | at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, |
345 | const char *parent_name, const u32 *divisors) | 339 | const char *parent_name, const u32 *divisors) |
346 | { | 340 | { |
347 | struct at91rm9200_clk_usb *usb; | 341 | struct at91rm9200_clk_usb *usb; |
@@ -359,7 +353,7 @@ at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, | |||
359 | init.flags = CLK_SET_RATE_PARENT; | 353 | init.flags = CLK_SET_RATE_PARENT; |
360 | 354 | ||
361 | usb->hw.init = &init; | 355 | usb->hw.init = &init; |
362 | usb->pmc = pmc; | 356 | usb->regmap = regmap; |
363 | memcpy(usb->divisors, divisors, sizeof(usb->divisors)); | 357 | memcpy(usb->divisors, divisors, sizeof(usb->divisors)); |
364 | 358 | ||
365 | clk = clk_register(NULL, &usb->hw); | 359 | clk = clk_register(NULL, &usb->hw); |
@@ -369,13 +363,13 @@ at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, | |||
369 | return clk; | 363 | return clk; |
370 | } | 364 | } |
371 | 365 | ||
372 | void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, | 366 | static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np) |
373 | struct at91_pmc *pmc) | ||
374 | { | 367 | { |
375 | struct clk *clk; | 368 | struct clk *clk; |
376 | int num_parents; | 369 | int num_parents; |
377 | const char *parent_names[USB_SOURCE_MAX]; | 370 | const char *parent_names[USB_SOURCE_MAX]; |
378 | const char *name = np->name; | 371 | const char *name = np->name; |
372 | struct regmap *regmap; | ||
379 | 373 | ||
380 | num_parents = of_clk_get_parent_count(np); | 374 | num_parents = of_clk_get_parent_count(np); |
381 | if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) | 375 | if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) |
@@ -385,19 +379,26 @@ void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, | |||
385 | 379 | ||
386 | of_property_read_string(np, "clock-output-names", &name); | 380 | of_property_read_string(np, "clock-output-names", &name); |
387 | 381 | ||
388 | clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents); | 382 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
383 | if (IS_ERR(regmap)) | ||
384 | return; | ||
385 | |||
386 | clk = at91sam9x5_clk_register_usb(regmap, name, parent_names, | ||
387 | num_parents); | ||
389 | if (IS_ERR(clk)) | 388 | if (IS_ERR(clk)) |
390 | return; | 389 | return; |
391 | 390 | ||
392 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 391 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
393 | } | 392 | } |
393 | CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb", | ||
394 | of_at91sam9x5_clk_usb_setup); | ||
394 | 395 | ||
395 | void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, | 396 | static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np) |
396 | struct at91_pmc *pmc) | ||
397 | { | 397 | { |
398 | struct clk *clk; | 398 | struct clk *clk; |
399 | const char *parent_name; | 399 | const char *parent_name; |
400 | const char *name = np->name; | 400 | const char *name = np->name; |
401 | struct regmap *regmap; | ||
401 | 402 | ||
402 | parent_name = of_clk_get_parent_name(np, 0); | 403 | parent_name = of_clk_get_parent_name(np, 0); |
403 | if (!parent_name) | 404 | if (!parent_name) |
@@ -405,20 +406,26 @@ void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, | |||
405 | 406 | ||
406 | of_property_read_string(np, "clock-output-names", &name); | 407 | of_property_read_string(np, "clock-output-names", &name); |
407 | 408 | ||
408 | clk = at91sam9n12_clk_register_usb(pmc, name, parent_name); | 409 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
410 | if (IS_ERR(regmap)) | ||
411 | return; | ||
412 | |||
413 | clk = at91sam9n12_clk_register_usb(regmap, name, parent_name); | ||
409 | if (IS_ERR(clk)) | 414 | if (IS_ERR(clk)) |
410 | return; | 415 | return; |
411 | 416 | ||
412 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 417 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
413 | } | 418 | } |
419 | CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb", | ||
420 | of_at91sam9n12_clk_usb_setup); | ||
414 | 421 | ||
415 | void __init of_at91rm9200_clk_usb_setup(struct device_node *np, | 422 | static void __init of_at91rm9200_clk_usb_setup(struct device_node *np) |
416 | struct at91_pmc *pmc) | ||
417 | { | 423 | { |
418 | struct clk *clk; | 424 | struct clk *clk; |
419 | const char *parent_name; | 425 | const char *parent_name; |
420 | const char *name = np->name; | 426 | const char *name = np->name; |
421 | u32 divisors[4] = {0, 0, 0, 0}; | 427 | u32 divisors[4] = {0, 0, 0, 0}; |
428 | struct regmap *regmap; | ||
422 | 429 | ||
423 | parent_name = of_clk_get_parent_name(np, 0); | 430 | parent_name = of_clk_get_parent_name(np, 0); |
424 | if (!parent_name) | 431 | if (!parent_name) |
@@ -430,9 +437,15 @@ void __init of_at91rm9200_clk_usb_setup(struct device_node *np, | |||
430 | 437 | ||
431 | of_property_read_string(np, "clock-output-names", &name); | 438 | of_property_read_string(np, "clock-output-names", &name); |
432 | 439 | ||
433 | clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors); | 440 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
441 | if (IS_ERR(regmap)) | ||
442 | return; | ||
443 | |||
444 | clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors); | ||
434 | if (IS_ERR(clk)) | 445 | if (IS_ERR(clk)) |
435 | return; | 446 | return; |
436 | 447 | ||
437 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 448 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
438 | } | 449 | } |
450 | CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb", | ||
451 | of_at91rm9200_clk_usb_setup); | ||
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c index ca561e90a60f..61fcf399e58c 100644 --- a/drivers/clk/at91/clk-utmi.c +++ b/drivers/clk/at91/clk-utmi.c | |||
@@ -11,14 +11,9 @@ | |||
11 | #include <linux/clk-provider.h> | 11 | #include <linux/clk-provider.h> |
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/of.h> | 14 | #include <linux/of.h> |
17 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
18 | #include <linux/of_irq.h> | 16 | #include <linux/regmap.h> |
19 | #include <linux/io.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/wait.h> | ||
22 | 17 | ||
23 | #include "pmc.h" | 18 | #include "pmc.h" |
24 | 19 | ||
@@ -26,37 +21,30 @@ | |||
26 | 21 | ||
27 | struct clk_utmi { | 22 | struct clk_utmi { |
28 | struct clk_hw hw; | 23 | struct clk_hw hw; |
29 | struct at91_pmc *pmc; | 24 | struct regmap *regmap; |
30 | unsigned int irq; | ||
31 | wait_queue_head_t wait; | ||
32 | }; | 25 | }; |
33 | 26 | ||
34 | #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw) | 27 | #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw) |
35 | 28 | ||
36 | static irqreturn_t clk_utmi_irq_handler(int irq, void *dev_id) | 29 | static inline bool clk_utmi_ready(struct regmap *regmap) |
37 | { | 30 | { |
38 | struct clk_utmi *utmi = (struct clk_utmi *)dev_id; | 31 | unsigned int status; |
39 | 32 | ||
40 | wake_up(&utmi->wait); | 33 | regmap_read(regmap, AT91_PMC_SR, &status); |
41 | disable_irq_nosync(utmi->irq); | ||
42 | 34 | ||
43 | return IRQ_HANDLED; | 35 | return status & AT91_PMC_LOCKU; |
44 | } | 36 | } |
45 | 37 | ||
46 | static int clk_utmi_prepare(struct clk_hw *hw) | 38 | static int clk_utmi_prepare(struct clk_hw *hw) |
47 | { | 39 | { |
48 | struct clk_utmi *utmi = to_clk_utmi(hw); | 40 | struct clk_utmi *utmi = to_clk_utmi(hw); |
49 | struct at91_pmc *pmc = utmi->pmc; | 41 | unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT | |
50 | u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) | AT91_PMC_UPLLEN | | 42 | AT91_PMC_BIASEN; |
51 | AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN; | ||
52 | 43 | ||
53 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); | 44 | regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, uckr, uckr); |
54 | 45 | ||
55 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU)) { | 46 | while (!clk_utmi_ready(utmi->regmap)) |
56 | enable_irq(utmi->irq); | 47 | cpu_relax(); |
57 | wait_event(utmi->wait, | ||
58 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU); | ||
59 | } | ||
60 | 48 | ||
61 | return 0; | 49 | return 0; |
62 | } | 50 | } |
@@ -64,18 +52,15 @@ static int clk_utmi_prepare(struct clk_hw *hw) | |||
64 | static int clk_utmi_is_prepared(struct clk_hw *hw) | 52 | static int clk_utmi_is_prepared(struct clk_hw *hw) |
65 | { | 53 | { |
66 | struct clk_utmi *utmi = to_clk_utmi(hw); | 54 | struct clk_utmi *utmi = to_clk_utmi(hw); |
67 | struct at91_pmc *pmc = utmi->pmc; | ||
68 | 55 | ||
69 | return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU); | 56 | return clk_utmi_ready(utmi->regmap); |
70 | } | 57 | } |
71 | 58 | ||
72 | static void clk_utmi_unprepare(struct clk_hw *hw) | 59 | static void clk_utmi_unprepare(struct clk_hw *hw) |
73 | { | 60 | { |
74 | struct clk_utmi *utmi = to_clk_utmi(hw); | 61 | struct clk_utmi *utmi = to_clk_utmi(hw); |
75 | struct at91_pmc *pmc = utmi->pmc; | ||
76 | u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN; | ||
77 | 62 | ||
78 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); | 63 | regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0); |
79 | } | 64 | } |
80 | 65 | ||
81 | static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw, | 66 | static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw, |
@@ -93,10 +78,9 @@ static const struct clk_ops utmi_ops = { | |||
93 | }; | 78 | }; |
94 | 79 | ||
95 | static struct clk * __init | 80 | static struct clk * __init |
96 | at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq, | 81 | at91_clk_register_utmi(struct regmap *regmap, |
97 | const char *name, const char *parent_name) | 82 | const char *name, const char *parent_name) |
98 | { | 83 | { |
99 | int ret; | ||
100 | struct clk_utmi *utmi; | 84 | struct clk_utmi *utmi; |
101 | struct clk *clk = NULL; | 85 | struct clk *clk = NULL; |
102 | struct clk_init_data init; | 86 | struct clk_init_data init; |
@@ -112,52 +96,36 @@ at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq, | |||
112 | init.flags = CLK_SET_RATE_GATE; | 96 | init.flags = CLK_SET_RATE_GATE; |
113 | 97 | ||
114 | utmi->hw.init = &init; | 98 | utmi->hw.init = &init; |
115 | utmi->pmc = pmc; | 99 | utmi->regmap = regmap; |
116 | utmi->irq = irq; | ||
117 | init_waitqueue_head(&utmi->wait); | ||
118 | irq_set_status_flags(utmi->irq, IRQ_NOAUTOEN); | ||
119 | ret = request_irq(utmi->irq, clk_utmi_irq_handler, | ||
120 | IRQF_TRIGGER_HIGH, "clk-utmi", utmi); | ||
121 | if (ret) { | ||
122 | kfree(utmi); | ||
123 | return ERR_PTR(ret); | ||
124 | } | ||
125 | 100 | ||
126 | clk = clk_register(NULL, &utmi->hw); | 101 | clk = clk_register(NULL, &utmi->hw); |
127 | if (IS_ERR(clk)) { | 102 | if (IS_ERR(clk)) |
128 | free_irq(utmi->irq, utmi); | ||
129 | kfree(utmi); | 103 | kfree(utmi); |
130 | } | ||
131 | 104 | ||
132 | return clk; | 105 | return clk; |
133 | } | 106 | } |
134 | 107 | ||
135 | static void __init | 108 | static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np) |
136 | of_at91_clk_utmi_setup(struct device_node *np, struct at91_pmc *pmc) | ||
137 | { | 109 | { |
138 | unsigned int irq; | ||
139 | struct clk *clk; | 110 | struct clk *clk; |
140 | const char *parent_name; | 111 | const char *parent_name; |
141 | const char *name = np->name; | 112 | const char *name = np->name; |
113 | struct regmap *regmap; | ||
142 | 114 | ||
143 | parent_name = of_clk_get_parent_name(np, 0); | 115 | parent_name = of_clk_get_parent_name(np, 0); |
144 | 116 | ||
145 | of_property_read_string(np, "clock-output-names", &name); | 117 | of_property_read_string(np, "clock-output-names", &name); |
146 | 118 | ||
147 | irq = irq_of_parse_and_map(np, 0); | 119 | regmap = syscon_node_to_regmap(of_get_parent(np)); |
148 | if (!irq) | 120 | if (IS_ERR(regmap)) |
149 | return; | 121 | return; |
150 | 122 | ||
151 | clk = at91_clk_register_utmi(pmc, irq, name, parent_name); | 123 | clk = at91_clk_register_utmi(regmap, name, parent_name); |
152 | if (IS_ERR(clk)) | 124 | if (IS_ERR(clk)) |
153 | return; | 125 | return; |
154 | 126 | ||
155 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 127 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
156 | return; | 128 | return; |
157 | } | 129 | } |
158 | 130 | CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi", | |
159 | void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np, | 131 | of_at91sam9x5_clk_utmi_setup); |
160 | struct at91_pmc *pmc) | ||
161 | { | ||
162 | of_at91_clk_utmi_setup(np, pmc); | ||
163 | } | ||
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 8476b570779b..526df5ba042d 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c | |||
@@ -12,36 +12,13 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk/at91_pmc.h> | 13 | #include <linux/clk/at91_pmc.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/io.h> | 16 | #include <linux/regmap.h> |
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/irqchip/chained_irq.h> | ||
20 | #include <linux/irqdomain.h> | ||
21 | #include <linux/of_irq.h> | ||
22 | 17 | ||
23 | #include <asm/proc-fns.h> | 18 | #include <asm/proc-fns.h> |
24 | 19 | ||
25 | #include "pmc.h" | 20 | #include "pmc.h" |
26 | 21 | ||
27 | void __iomem *at91_pmc_base; | ||
28 | EXPORT_SYMBOL_GPL(at91_pmc_base); | ||
29 | |||
30 | void at91rm9200_idle(void) | ||
31 | { | ||
32 | /* | ||
33 | * Disable the processor clock. The processor will be automatically | ||
34 | * re-enabled by an interrupt or by a reset. | ||
35 | */ | ||
36 | at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); | ||
37 | } | ||
38 | |||
39 | void at91sam9_idle(void) | ||
40 | { | ||
41 | at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); | ||
42 | cpu_do_idle(); | ||
43 | } | ||
44 | |||
45 | int of_at91_get_clk_range(struct device_node *np, const char *propname, | 22 | int of_at91_get_clk_range(struct device_node *np, const char *propname, |
46 | struct clk_range *range) | 23 | struct clk_range *range) |
47 | { | 24 | { |
@@ -64,402 +41,3 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname, | |||
64 | return 0; | 41 | return 0; |
65 | } | 42 | } |
66 | EXPORT_SYMBOL_GPL(of_at91_get_clk_range); | 43 | EXPORT_SYMBOL_GPL(of_at91_get_clk_range); |
67 | |||
68 | static void pmc_irq_mask(struct irq_data *d) | ||
69 | { | ||
70 | struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); | ||
71 | |||
72 | pmc_write(pmc, AT91_PMC_IDR, 1 << d->hwirq); | ||
73 | } | ||
74 | |||
75 | static void pmc_irq_unmask(struct irq_data *d) | ||
76 | { | ||
77 | struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); | ||
78 | |||
79 | pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq); | ||
80 | } | ||
81 | |||
82 | static int pmc_irq_set_type(struct irq_data *d, unsigned type) | ||
83 | { | ||
84 | if (type != IRQ_TYPE_LEVEL_HIGH) { | ||
85 | pr_warn("PMC: type not supported (support only IRQ_TYPE_LEVEL_HIGH type)\n"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static void pmc_irq_suspend(struct irq_data *d) | ||
93 | { | ||
94 | struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); | ||
95 | |||
96 | pmc->imr = pmc_read(pmc, AT91_PMC_IMR); | ||
97 | pmc_write(pmc, AT91_PMC_IDR, pmc->imr); | ||
98 | } | ||
99 | |||
100 | static void pmc_irq_resume(struct irq_data *d) | ||
101 | { | ||
102 | struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); | ||
103 | |||
104 | pmc_write(pmc, AT91_PMC_IER, pmc->imr); | ||
105 | } | ||
106 | |||
107 | static struct irq_chip pmc_irq = { | ||
108 | .name = "PMC", | ||
109 | .irq_disable = pmc_irq_mask, | ||
110 | .irq_mask = pmc_irq_mask, | ||
111 | .irq_unmask = pmc_irq_unmask, | ||
112 | .irq_set_type = pmc_irq_set_type, | ||
113 | .irq_suspend = pmc_irq_suspend, | ||
114 | .irq_resume = pmc_irq_resume, | ||
115 | }; | ||
116 | |||
117 | static struct lock_class_key pmc_lock_class; | ||
118 | |||
119 | static int pmc_irq_map(struct irq_domain *h, unsigned int virq, | ||
120 | irq_hw_number_t hw) | ||
121 | { | ||
122 | struct at91_pmc *pmc = h->host_data; | ||
123 | |||
124 | irq_set_lockdep_class(virq, &pmc_lock_class); | ||
125 | |||
126 | irq_set_chip_and_handler(virq, &pmc_irq, | ||
127 | handle_level_irq); | ||
128 | irq_set_chip_data(virq, pmc); | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int pmc_irq_domain_xlate(struct irq_domain *d, | ||
134 | struct device_node *ctrlr, | ||
135 | const u32 *intspec, unsigned int intsize, | ||
136 | irq_hw_number_t *out_hwirq, | ||
137 | unsigned int *out_type) | ||
138 | { | ||
139 | struct at91_pmc *pmc = d->host_data; | ||
140 | const struct at91_pmc_caps *caps = pmc->caps; | ||
141 | |||
142 | if (WARN_ON(intsize < 1)) | ||
143 | return -EINVAL; | ||
144 | |||
145 | *out_hwirq = intspec[0]; | ||
146 | |||
147 | if (!(caps->available_irqs & (1 << *out_hwirq))) | ||
148 | return -EINVAL; | ||
149 | |||
150 | *out_type = IRQ_TYPE_LEVEL_HIGH; | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static const struct irq_domain_ops pmc_irq_ops = { | ||
156 | .map = pmc_irq_map, | ||
157 | .xlate = pmc_irq_domain_xlate, | ||
158 | }; | ||
159 | |||
160 | static irqreturn_t pmc_irq_handler(int irq, void *data) | ||
161 | { | ||
162 | struct at91_pmc *pmc = (struct at91_pmc *)data; | ||
163 | unsigned long sr; | ||
164 | int n; | ||
165 | |||
166 | sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR); | ||
167 | if (!sr) | ||
168 | return IRQ_NONE; | ||
169 | |||
170 | for_each_set_bit(n, &sr, BITS_PER_LONG) | ||
171 | generic_handle_irq(irq_find_mapping(pmc->irqdomain, n)); | ||
172 | |||
173 | return IRQ_HANDLED; | ||
174 | } | ||
175 | |||
176 | static const struct at91_pmc_caps at91rm9200_caps = { | ||
177 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | | ||
178 | AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | | ||
179 | AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | | ||
180 | AT91_PMC_PCK3RDY, | ||
181 | }; | ||
182 | |||
183 | static const struct at91_pmc_caps at91sam9260_caps = { | ||
184 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | | ||
185 | AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | | ||
186 | AT91_PMC_PCK1RDY, | ||
187 | }; | ||
188 | |||
189 | static const struct at91_pmc_caps at91sam9g45_caps = { | ||
190 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
191 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
192 | AT91_PMC_PCK1RDY, | ||
193 | }; | ||
194 | |||
195 | static const struct at91_pmc_caps at91sam9n12_caps = { | ||
196 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | | ||
197 | AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | | ||
198 | AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | | ||
199 | AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, | ||
200 | }; | ||
201 | |||
202 | static const struct at91_pmc_caps at91sam9x5_caps = { | ||
203 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
204 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
205 | AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | | ||
206 | AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, | ||
207 | }; | ||
208 | |||
209 | static const struct at91_pmc_caps sama5d2_caps = { | ||
210 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
211 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
212 | AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | | ||
213 | AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | | ||
214 | AT91_PMC_CFDEV | AT91_PMC_GCKRDY, | ||
215 | }; | ||
216 | |||
217 | static const struct at91_pmc_caps sama5d3_caps = { | ||
218 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
219 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
220 | AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | | ||
221 | AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | | ||
222 | AT91_PMC_CFDEV, | ||
223 | }; | ||
224 | |||
225 | static struct at91_pmc *__init at91_pmc_init(struct device_node *np, | ||
226 | void __iomem *regbase, int virq, | ||
227 | const struct at91_pmc_caps *caps) | ||
228 | { | ||
229 | struct at91_pmc *pmc; | ||
230 | |||
231 | if (!regbase || !virq || !caps) | ||
232 | return NULL; | ||
233 | |||
234 | at91_pmc_base = regbase; | ||
235 | |||
236 | pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); | ||
237 | if (!pmc) | ||
238 | return NULL; | ||
239 | |||
240 | spin_lock_init(&pmc->lock); | ||
241 | pmc->regbase = regbase; | ||
242 | pmc->virq = virq; | ||
243 | pmc->caps = caps; | ||
244 | |||
245 | pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc); | ||
246 | |||
247 | if (!pmc->irqdomain) | ||
248 | goto out_free_pmc; | ||
249 | |||
250 | pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); | ||
251 | if (request_irq(pmc->virq, pmc_irq_handler, | ||
252 | IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc)) | ||
253 | goto out_remove_irqdomain; | ||
254 | |||
255 | return pmc; | ||
256 | |||
257 | out_remove_irqdomain: | ||
258 | irq_domain_remove(pmc->irqdomain); | ||
259 | out_free_pmc: | ||
260 | kfree(pmc); | ||
261 | |||
262 | return NULL; | ||
263 | } | ||
264 | |||
265 | static const struct of_device_id pmc_clk_ids[] __initconst = { | ||
266 | /* Slow oscillator */ | ||
267 | { | ||
268 | .compatible = "atmel,at91sam9260-clk-slow", | ||
269 | .data = of_at91sam9260_clk_slow_setup, | ||
270 | }, | ||
271 | /* Main clock */ | ||
272 | { | ||
273 | .compatible = "atmel,at91rm9200-clk-main-osc", | ||
274 | .data = of_at91rm9200_clk_main_osc_setup, | ||
275 | }, | ||
276 | { | ||
277 | .compatible = "atmel,at91sam9x5-clk-main-rc-osc", | ||
278 | .data = of_at91sam9x5_clk_main_rc_osc_setup, | ||
279 | }, | ||
280 | { | ||
281 | .compatible = "atmel,at91rm9200-clk-main", | ||
282 | .data = of_at91rm9200_clk_main_setup, | ||
283 | }, | ||
284 | { | ||
285 | .compatible = "atmel,at91sam9x5-clk-main", | ||
286 | .data = of_at91sam9x5_clk_main_setup, | ||
287 | }, | ||
288 | /* PLL clocks */ | ||
289 | { | ||
290 | .compatible = "atmel,at91rm9200-clk-pll", | ||
291 | .data = of_at91rm9200_clk_pll_setup, | ||
292 | }, | ||
293 | { | ||
294 | .compatible = "atmel,at91sam9g45-clk-pll", | ||
295 | .data = of_at91sam9g45_clk_pll_setup, | ||
296 | }, | ||
297 | { | ||
298 | .compatible = "atmel,at91sam9g20-clk-pllb", | ||
299 | .data = of_at91sam9g20_clk_pllb_setup, | ||
300 | }, | ||
301 | { | ||
302 | .compatible = "atmel,sama5d3-clk-pll", | ||
303 | .data = of_sama5d3_clk_pll_setup, | ||
304 | }, | ||
305 | { | ||
306 | .compatible = "atmel,at91sam9x5-clk-plldiv", | ||
307 | .data = of_at91sam9x5_clk_plldiv_setup, | ||
308 | }, | ||
309 | /* Master clock */ | ||
310 | { | ||
311 | .compatible = "atmel,at91rm9200-clk-master", | ||
312 | .data = of_at91rm9200_clk_master_setup, | ||
313 | }, | ||
314 | { | ||
315 | .compatible = "atmel,at91sam9x5-clk-master", | ||
316 | .data = of_at91sam9x5_clk_master_setup, | ||
317 | }, | ||
318 | /* System clocks */ | ||
319 | { | ||
320 | .compatible = "atmel,at91rm9200-clk-system", | ||
321 | .data = of_at91rm9200_clk_sys_setup, | ||
322 | }, | ||
323 | /* Peripheral clocks */ | ||
324 | { | ||
325 | .compatible = "atmel,at91rm9200-clk-peripheral", | ||
326 | .data = of_at91rm9200_clk_periph_setup, | ||
327 | }, | ||
328 | { | ||
329 | .compatible = "atmel,at91sam9x5-clk-peripheral", | ||
330 | .data = of_at91sam9x5_clk_periph_setup, | ||
331 | }, | ||
332 | /* Programmable clocks */ | ||
333 | { | ||
334 | .compatible = "atmel,at91rm9200-clk-programmable", | ||
335 | .data = of_at91rm9200_clk_prog_setup, | ||
336 | }, | ||
337 | { | ||
338 | .compatible = "atmel,at91sam9g45-clk-programmable", | ||
339 | .data = of_at91sam9g45_clk_prog_setup, | ||
340 | }, | ||
341 | { | ||
342 | .compatible = "atmel,at91sam9x5-clk-programmable", | ||
343 | .data = of_at91sam9x5_clk_prog_setup, | ||
344 | }, | ||
345 | /* UTMI clock */ | ||
346 | #if defined(CONFIG_HAVE_AT91_UTMI) | ||
347 | { | ||
348 | .compatible = "atmel,at91sam9x5-clk-utmi", | ||
349 | .data = of_at91sam9x5_clk_utmi_setup, | ||
350 | }, | ||
351 | #endif | ||
352 | /* USB clock */ | ||
353 | #if defined(CONFIG_HAVE_AT91_USB_CLK) | ||
354 | { | ||
355 | .compatible = "atmel,at91rm9200-clk-usb", | ||
356 | .data = of_at91rm9200_clk_usb_setup, | ||
357 | }, | ||
358 | { | ||
359 | .compatible = "atmel,at91sam9x5-clk-usb", | ||
360 | .data = of_at91sam9x5_clk_usb_setup, | ||
361 | }, | ||
362 | { | ||
363 | .compatible = "atmel,at91sam9n12-clk-usb", | ||
364 | .data = of_at91sam9n12_clk_usb_setup, | ||
365 | }, | ||
366 | #endif | ||
367 | /* SMD clock */ | ||
368 | #if defined(CONFIG_HAVE_AT91_SMD) | ||
369 | { | ||
370 | .compatible = "atmel,at91sam9x5-clk-smd", | ||
371 | .data = of_at91sam9x5_clk_smd_setup, | ||
372 | }, | ||
373 | #endif | ||
374 | #if defined(CONFIG_HAVE_AT91_H32MX) | ||
375 | { | ||
376 | .compatible = "atmel,sama5d4-clk-h32mx", | ||
377 | .data = of_sama5d4_clk_h32mx_setup, | ||
378 | }, | ||
379 | #endif | ||
380 | #if defined(CONFIG_HAVE_AT91_GENERATED_CLK) | ||
381 | { | ||
382 | .compatible = "atmel,sama5d2-clk-generated", | ||
383 | .data = of_sama5d2_clk_generated_setup, | ||
384 | }, | ||
385 | #endif | ||
386 | { /*sentinel*/ } | ||
387 | }; | ||
388 | |||
389 | static void __init of_at91_pmc_setup(struct device_node *np, | ||
390 | const struct at91_pmc_caps *caps) | ||
391 | { | ||
392 | struct at91_pmc *pmc; | ||
393 | struct device_node *childnp; | ||
394 | void (*clk_setup)(struct device_node *, struct at91_pmc *); | ||
395 | const struct of_device_id *clk_id; | ||
396 | void __iomem *regbase = of_iomap(np, 0); | ||
397 | int virq; | ||
398 | |||
399 | if (!regbase) | ||
400 | return; | ||
401 | |||
402 | virq = irq_of_parse_and_map(np, 0); | ||
403 | if (!virq) | ||
404 | return; | ||
405 | |||
406 | pmc = at91_pmc_init(np, regbase, virq, caps); | ||
407 | if (!pmc) | ||
408 | return; | ||
409 | for_each_child_of_node(np, childnp) { | ||
410 | clk_id = of_match_node(pmc_clk_ids, childnp); | ||
411 | if (!clk_id) | ||
412 | continue; | ||
413 | clk_setup = clk_id->data; | ||
414 | clk_setup(childnp, pmc); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | static void __init of_at91rm9200_pmc_setup(struct device_node *np) | ||
419 | { | ||
420 | of_at91_pmc_setup(np, &at91rm9200_caps); | ||
421 | } | ||
422 | CLK_OF_DECLARE(at91rm9200_clk_pmc, "atmel,at91rm9200-pmc", | ||
423 | of_at91rm9200_pmc_setup); | ||
424 | |||
425 | static void __init of_at91sam9260_pmc_setup(struct device_node *np) | ||
426 | { | ||
427 | of_at91_pmc_setup(np, &at91sam9260_caps); | ||
428 | } | ||
429 | CLK_OF_DECLARE(at91sam9260_clk_pmc, "atmel,at91sam9260-pmc", | ||
430 | of_at91sam9260_pmc_setup); | ||
431 | |||
432 | static void __init of_at91sam9g45_pmc_setup(struct device_node *np) | ||
433 | { | ||
434 | of_at91_pmc_setup(np, &at91sam9g45_caps); | ||
435 | } | ||
436 | CLK_OF_DECLARE(at91sam9g45_clk_pmc, "atmel,at91sam9g45-pmc", | ||
437 | of_at91sam9g45_pmc_setup); | ||
438 | |||
439 | static void __init of_at91sam9n12_pmc_setup(struct device_node *np) | ||
440 | { | ||
441 | of_at91_pmc_setup(np, &at91sam9n12_caps); | ||
442 | } | ||
443 | CLK_OF_DECLARE(at91sam9n12_clk_pmc, "atmel,at91sam9n12-pmc", | ||
444 | of_at91sam9n12_pmc_setup); | ||
445 | |||
446 | static void __init of_at91sam9x5_pmc_setup(struct device_node *np) | ||
447 | { | ||
448 | of_at91_pmc_setup(np, &at91sam9x5_caps); | ||
449 | } | ||
450 | CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", | ||
451 | of_at91sam9x5_pmc_setup); | ||
452 | |||
453 | static void __init of_sama5d2_pmc_setup(struct device_node *np) | ||
454 | { | ||
455 | of_at91_pmc_setup(np, &sama5d2_caps); | ||
456 | } | ||
457 | CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc", | ||
458 | of_sama5d2_pmc_setup); | ||
459 | |||
460 | static void __init of_sama5d3_pmc_setup(struct device_node *np) | ||
461 | { | ||
462 | of_at91_pmc_setup(np, &sama5d3_caps); | ||
463 | } | ||
464 | CLK_OF_DECLARE(sama5d3_clk_pmc, "atmel,sama5d3-pmc", | ||
465 | of_sama5d3_pmc_setup); | ||
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index f65739272779..5771fff0ee3f 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h | |||
@@ -14,8 +14,11 @@ | |||
14 | 14 | ||
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/irqdomain.h> | 16 | #include <linux/irqdomain.h> |
17 | #include <linux/regmap.h> | ||
17 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
18 | 19 | ||
20 | extern spinlock_t pmc_pcr_lock; | ||
21 | |||
19 | struct clk_range { | 22 | struct clk_range { |
20 | unsigned long min; | 23 | unsigned long min; |
21 | unsigned long max; | 24 | unsigned long max; |
@@ -23,102 +26,7 @@ struct clk_range { | |||
23 | 26 | ||
24 | #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,} | 27 | #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,} |
25 | 28 | ||
26 | struct at91_pmc_caps { | ||
27 | u32 available_irqs; | ||
28 | }; | ||
29 | |||
30 | struct at91_pmc { | ||
31 | void __iomem *regbase; | ||
32 | int virq; | ||
33 | spinlock_t lock; | ||
34 | const struct at91_pmc_caps *caps; | ||
35 | struct irq_domain *irqdomain; | ||
36 | u32 imr; | ||
37 | }; | ||
38 | |||
39 | static inline void pmc_lock(struct at91_pmc *pmc) | ||
40 | { | ||
41 | spin_lock(&pmc->lock); | ||
42 | } | ||
43 | |||
44 | static inline void pmc_unlock(struct at91_pmc *pmc) | ||
45 | { | ||
46 | spin_unlock(&pmc->lock); | ||
47 | } | ||
48 | |||
49 | static inline u32 pmc_read(struct at91_pmc *pmc, int offset) | ||
50 | { | ||
51 | return readl(pmc->regbase + offset); | ||
52 | } | ||
53 | |||
54 | static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value) | ||
55 | { | ||
56 | writel(value, pmc->regbase + offset); | ||
57 | } | ||
58 | |||
59 | int of_at91_get_clk_range(struct device_node *np, const char *propname, | 29 | int of_at91_get_clk_range(struct device_node *np, const char *propname, |
60 | struct clk_range *range); | 30 | struct clk_range *range); |
61 | 31 | ||
62 | void of_at91sam9260_clk_slow_setup(struct device_node *np, | ||
63 | struct at91_pmc *pmc); | ||
64 | |||
65 | void of_at91rm9200_clk_main_osc_setup(struct device_node *np, | ||
66 | struct at91_pmc *pmc); | ||
67 | void of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np, | ||
68 | struct at91_pmc *pmc); | ||
69 | void of_at91rm9200_clk_main_setup(struct device_node *np, | ||
70 | struct at91_pmc *pmc); | ||
71 | void of_at91sam9x5_clk_main_setup(struct device_node *np, | ||
72 | struct at91_pmc *pmc); | ||
73 | |||
74 | void of_at91rm9200_clk_pll_setup(struct device_node *np, | ||
75 | struct at91_pmc *pmc); | ||
76 | void of_at91sam9g45_clk_pll_setup(struct device_node *np, | ||
77 | struct at91_pmc *pmc); | ||
78 | void of_at91sam9g20_clk_pllb_setup(struct device_node *np, | ||
79 | struct at91_pmc *pmc); | ||
80 | void of_sama5d3_clk_pll_setup(struct device_node *np, | ||
81 | struct at91_pmc *pmc); | ||
82 | void of_at91sam9x5_clk_plldiv_setup(struct device_node *np, | ||
83 | struct at91_pmc *pmc); | ||
84 | |||
85 | void of_at91rm9200_clk_master_setup(struct device_node *np, | ||
86 | struct at91_pmc *pmc); | ||
87 | void of_at91sam9x5_clk_master_setup(struct device_node *np, | ||
88 | struct at91_pmc *pmc); | ||
89 | |||
90 | void of_at91rm9200_clk_sys_setup(struct device_node *np, | ||
91 | struct at91_pmc *pmc); | ||
92 | |||
93 | void of_at91rm9200_clk_periph_setup(struct device_node *np, | ||
94 | struct at91_pmc *pmc); | ||
95 | void of_at91sam9x5_clk_periph_setup(struct device_node *np, | ||
96 | struct at91_pmc *pmc); | ||
97 | |||
98 | void of_at91rm9200_clk_prog_setup(struct device_node *np, | ||
99 | struct at91_pmc *pmc); | ||
100 | void of_at91sam9g45_clk_prog_setup(struct device_node *np, | ||
101 | struct at91_pmc *pmc); | ||
102 | void of_at91sam9x5_clk_prog_setup(struct device_node *np, | ||
103 | struct at91_pmc *pmc); | ||
104 | |||
105 | void of_at91sam9x5_clk_utmi_setup(struct device_node *np, | ||
106 | struct at91_pmc *pmc); | ||
107 | |||
108 | void of_at91rm9200_clk_usb_setup(struct device_node *np, | ||
109 | struct at91_pmc *pmc); | ||
110 | void of_at91sam9x5_clk_usb_setup(struct device_node *np, | ||
111 | struct at91_pmc *pmc); | ||
112 | void of_at91sam9n12_clk_usb_setup(struct device_node *np, | ||
113 | struct at91_pmc *pmc); | ||
114 | |||
115 | void of_at91sam9x5_clk_smd_setup(struct device_node *np, | ||
116 | struct at91_pmc *pmc); | ||
117 | |||
118 | void of_sama5d4_clk_h32mx_setup(struct device_node *np, | ||
119 | struct at91_pmc *pmc); | ||
120 | |||
121 | void of_sama5d2_clk_generated_setup(struct device_node *np, | ||
122 | struct at91_pmc *pmc); | ||
123 | |||
124 | #endif /* __PMC_H_ */ | 32 | #endif /* __PMC_H_ */ |
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 051a8a8224cd..a145b319d171 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
@@ -576,10 +576,8 @@ static struct cpufreq_driver s5pv210_driver = { | |||
576 | .get = cpufreq_generic_get, | 576 | .get = cpufreq_generic_get, |
577 | .init = s5pv210_cpu_init, | 577 | .init = s5pv210_cpu_init, |
578 | .name = "s5pv210", | 578 | .name = "s5pv210", |
579 | #ifdef CONFIG_PM | ||
580 | .suspend = cpufreq_generic_suspend, | 579 | .suspend = cpufreq_generic_suspend, |
581 | .resume = cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */ | 580 | .resume = cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */ |
582 | #endif | ||
583 | }; | 581 | }; |
584 | 582 | ||
585 | static struct notifier_block s5pv210_cpufreq_reboot_notifier = { | 583 | static struct notifier_block s5pv210_cpufreq_reboot_notifier = { |
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 6174db80c663..7e3e595c9f30 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c | |||
@@ -80,7 +80,7 @@ | |||
80 | #define FW_REV_MINOR(x) (((x) & FW_REV_MINOR_MASK) >> FW_REV_MINOR_BITS) | 80 | #define FW_REV_MINOR(x) (((x) & FW_REV_MINOR_MASK) >> FW_REV_MINOR_BITS) |
81 | #define FW_REV_PATCH(x) ((x) & FW_REV_PATCH_MASK) | 81 | #define FW_REV_PATCH(x) ((x) & FW_REV_PATCH_MASK) |
82 | 82 | ||
83 | #define MAX_RX_TIMEOUT (msecs_to_jiffies(20)) | 83 | #define MAX_RX_TIMEOUT (msecs_to_jiffies(30)) |
84 | 84 | ||
85 | enum scpi_error_codes { | 85 | enum scpi_error_codes { |
86 | SCPI_SUCCESS = 0, /* Success */ | 86 | SCPI_SUCCESS = 0, /* Success */ |
@@ -231,7 +231,8 @@ struct _scpi_sensor_info { | |||
231 | }; | 231 | }; |
232 | 232 | ||
233 | struct sensor_value { | 233 | struct sensor_value { |
234 | __le32 val; | 234 | __le32 lo_val; |
235 | __le32 hi_val; | ||
235 | } __packed; | 236 | } __packed; |
236 | 237 | ||
237 | static struct scpi_drvinfo *scpi_info; | 238 | static struct scpi_drvinfo *scpi_info; |
@@ -373,7 +374,7 @@ static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len, | |||
373 | ret = -ETIMEDOUT; | 374 | ret = -ETIMEDOUT; |
374 | else | 375 | else |
375 | /* first status word */ | 376 | /* first status word */ |
376 | ret = le32_to_cpu(msg->status); | 377 | ret = msg->status; |
377 | out: | 378 | out: |
378 | if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */ | 379 | if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */ |
379 | scpi_process_cmd(scpi_chan, msg->cmd); | 380 | scpi_process_cmd(scpi_chan, msg->cmd); |
@@ -525,15 +526,17 @@ static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info) | |||
525 | return ret; | 526 | return ret; |
526 | } | 527 | } |
527 | 528 | ||
528 | int scpi_sensor_get_value(u16 sensor, u32 *val) | 529 | int scpi_sensor_get_value(u16 sensor, u64 *val) |
529 | { | 530 | { |
531 | __le16 id = cpu_to_le16(sensor); | ||
530 | struct sensor_value buf; | 532 | struct sensor_value buf; |
531 | int ret; | 533 | int ret; |
532 | 534 | ||
533 | ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor), | 535 | ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &id, sizeof(id), |
534 | &buf, sizeof(buf)); | 536 | &buf, sizeof(buf)); |
535 | if (!ret) | 537 | if (!ret) |
536 | *val = le32_to_cpu(buf.val); | 538 | *val = (u64)le32_to_cpu(buf.hi_val) << 32 | |
539 | le32_to_cpu(buf.lo_val); | ||
537 | 540 | ||
538 | return ret; | 541 | return ret; |
539 | } | 542 | } |
@@ -699,7 +702,7 @@ static int scpi_probe(struct platform_device *pdev) | |||
699 | cl->rx_callback = scpi_handle_remote_msg; | 702 | cl->rx_callback = scpi_handle_remote_msg; |
700 | cl->tx_prepare = scpi_tx_prepare; | 703 | cl->tx_prepare = scpi_tx_prepare; |
701 | cl->tx_block = true; | 704 | cl->tx_block = true; |
702 | cl->tx_tout = 50; | 705 | cl->tx_tout = 20; |
703 | cl->knows_txdone = false; /* controller can't ack */ | 706 | cl->knows_txdone = false; /* controller can't ack */ |
704 | 707 | ||
705 | INIT_LIST_HEAD(&pchan->rx_pending); | 708 | INIT_LIST_HEAD(&pchan->rx_pending); |
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index 7e20567bc369..912b449c8303 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c | |||
@@ -52,7 +52,7 @@ static int scpi_read_temp(void *dev, int *temp) | |||
52 | struct scpi_sensors *scpi_sensors = zone->scpi_sensors; | 52 | struct scpi_sensors *scpi_sensors = zone->scpi_sensors; |
53 | struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; | 53 | struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; |
54 | struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; | 54 | struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; |
55 | u32 value; | 55 | u64 value; |
56 | int ret; | 56 | int ret; |
57 | 57 | ||
58 | ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); | 58 | ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); |
@@ -70,7 +70,7 @@ scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) | |||
70 | struct scpi_sensors *scpi_sensors = dev_get_drvdata(dev); | 70 | struct scpi_sensors *scpi_sensors = dev_get_drvdata(dev); |
71 | struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; | 71 | struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; |
72 | struct sensor_data *sensor; | 72 | struct sensor_data *sensor; |
73 | u32 value; | 73 | u64 value; |
74 | int ret; | 74 | int ret; |
75 | 75 | ||
76 | sensor = container_of(attr, struct sensor_data, dev_attr_input); | 76 | sensor = container_of(attr, struct sensor_data, dev_attr_input); |
@@ -79,7 +79,7 @@ scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) | |||
79 | if (ret) | 79 | if (ret) |
80 | return ret; | 80 | return ret; |
81 | 81 | ||
82 | return sprintf(buf, "%u\n", value); | 82 | return sprintf(buf, "%llu\n", value); |
83 | } | 83 | } |
84 | 84 | ||
85 | static ssize_t | 85 | static ssize_t |
@@ -114,6 +114,7 @@ static int scpi_hwmon_probe(struct platform_device *pdev) | |||
114 | { | 114 | { |
115 | u16 nr_sensors, i; | 115 | u16 nr_sensors, i; |
116 | int num_temp = 0, num_volt = 0, num_current = 0, num_power = 0; | 116 | int num_temp = 0, num_volt = 0, num_current = 0, num_power = 0; |
117 | int num_energy = 0; | ||
117 | struct scpi_ops *scpi_ops; | 118 | struct scpi_ops *scpi_ops; |
118 | struct device *hwdev, *dev = &pdev->dev; | 119 | struct device *hwdev, *dev = &pdev->dev; |
119 | struct scpi_sensors *scpi_sensors; | 120 | struct scpi_sensors *scpi_sensors; |
@@ -182,6 +183,13 @@ static int scpi_hwmon_probe(struct platform_device *pdev) | |||
182 | "power%d_label", num_power + 1); | 183 | "power%d_label", num_power + 1); |
183 | num_power++; | 184 | num_power++; |
184 | break; | 185 | break; |
186 | case ENERGY: | ||
187 | snprintf(sensor->input, sizeof(sensor->input), | ||
188 | "energy%d_input", num_energy + 1); | ||
189 | snprintf(sensor->label, sizeof(sensor->input), | ||
190 | "energy%d_label", num_energy + 1); | ||
191 | num_energy++; | ||
192 | break; | ||
185 | default: | 193 | default: |
186 | continue; | 194 | continue; |
187 | } | 195 | } |
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 6515dfc2b805..21825ddce4a3 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c | |||
@@ -541,9 +541,20 @@ static void gpmc_cs_show_timings(int cs, const char *desc) | |||
541 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 0, 3, "adv-on-ns"); | 541 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 0, 3, "adv-on-ns"); |
542 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 8, 12, "adv-rd-off-ns"); | 542 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 8, 12, "adv-rd-off-ns"); |
543 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns"); | 543 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns"); |
544 | if (gpmc_capability & GPMC_HAS_MUX_AAD) { | ||
545 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 4, 6, "adv-aad-mux-on-ns"); | ||
546 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 24, 26, | ||
547 | "adv-aad-mux-rd-off-ns"); | ||
548 | GPMC_GET_TICKS(GPMC_CS_CONFIG3, 28, 30, | ||
549 | "adv-aad-mux-wr-off-ns"); | ||
550 | } | ||
544 | 551 | ||
545 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 0, 3, "oe-on-ns"); | 552 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 0, 3, "oe-on-ns"); |
546 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 8, 12, "oe-off-ns"); | 553 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 8, 12, "oe-off-ns"); |
554 | if (gpmc_capability & GPMC_HAS_MUX_AAD) { | ||
555 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 4, 6, "oe-aad-mux-on-ns"); | ||
556 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 13, 15, "oe-aad-mux-off-ns"); | ||
557 | } | ||
547 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns"); | 558 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns"); |
548 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns"); | 559 | GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns"); |
549 | 560 | ||
@@ -734,9 +745,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, | |||
734 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); | 745 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); |
735 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off); | 746 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off); |
736 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off); | 747 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off); |
748 | if (gpmc_capability & GPMC_HAS_MUX_AAD) { | ||
749 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 4, 6, adv_aad_mux_on); | ||
750 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 24, 26, adv_aad_mux_rd_off); | ||
751 | GPMC_SET_ONE(GPMC_CS_CONFIG3, 28, 30, adv_aad_mux_wr_off); | ||
752 | } | ||
737 | 753 | ||
738 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); | 754 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); |
739 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off); | 755 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off); |
756 | if (gpmc_capability & GPMC_HAS_MUX_AAD) { | ||
757 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 4, 6, oe_aad_mux_on); | ||
758 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 13, 15, oe_aad_mux_off); | ||
759 | } | ||
740 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on); | 760 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on); |
741 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off); | 761 | GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off); |
742 | 762 | ||
@@ -1722,6 +1742,12 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, | |||
1722 | of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); | 1742 | of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); |
1723 | of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); | 1743 | of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); |
1724 | of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); | 1744 | of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); |
1745 | of_property_read_u32(np, "gpmc,adv-aad-mux-on-ns", | ||
1746 | &gpmc_t->adv_aad_mux_on); | ||
1747 | of_property_read_u32(np, "gpmc,adv-aad-mux-rd-off-ns", | ||
1748 | &gpmc_t->adv_aad_mux_rd_off); | ||
1749 | of_property_read_u32(np, "gpmc,adv-aad-mux-wr-off-ns", | ||
1750 | &gpmc_t->adv_aad_mux_wr_off); | ||
1725 | 1751 | ||
1726 | /* WE signal timings */ | 1752 | /* WE signal timings */ |
1727 | of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); | 1753 | of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); |
@@ -1730,6 +1756,10 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, | |||
1730 | /* OE signal timings */ | 1756 | /* OE signal timings */ |
1731 | of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); | 1757 | of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); |
1732 | of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); | 1758 | of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); |
1759 | of_property_read_u32(np, "gpmc,oe-aad-mux-on-ns", | ||
1760 | &gpmc_t->oe_aad_mux_on); | ||
1761 | of_property_read_u32(np, "gpmc,oe-aad-mux-off-ns", | ||
1762 | &gpmc_t->oe_aad_mux_off); | ||
1733 | 1763 | ||
1734 | /* access and cycle timings */ | 1764 | /* access and cycle timings */ |
1735 | of_property_read_u32(np, "gpmc,page-burst-access-ns", | 1765 | of_property_read_u32(np, "gpmc,page-burst-access-ns", |
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 4d7178e46afa..a1fc8eda79f3 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile | |||
@@ -2,6 +2,7 @@ obj-y += core.o | |||
2 | obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o | 2 | obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o |
3 | obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o | 3 | obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o |
4 | obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o | 4 | obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o |
5 | obj-$(CONFIG_MACH_PISTACHIO) += reset-pistachio.o | ||
5 | obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o | 6 | obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o |
6 | obj-$(CONFIG_ARCH_STI) += sti/ | 7 | obj-$(CONFIG_ARCH_STI) += sti/ |
7 | obj-$(CONFIG_ARCH_HISI) += hisilicon/ | 8 | obj-$(CONFIG_ARCH_HISI) += hisilicon/ |
diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 87376638948d..f15f150b79da 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c | |||
@@ -45,9 +45,6 @@ struct reset_control { | |||
45 | static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, | 45 | static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, |
46 | const struct of_phandle_args *reset_spec) | 46 | const struct of_phandle_args *reset_spec) |
47 | { | 47 | { |
48 | if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) | ||
49 | return -EINVAL; | ||
50 | |||
51 | if (reset_spec->args[0] >= rcdev->nr_resets) | 48 | if (reset_spec->args[0] >= rcdev->nr_resets) |
52 | return -EINVAL; | 49 | return -EINVAL; |
53 | 50 | ||
@@ -152,7 +149,7 @@ EXPORT_SYMBOL_GPL(reset_control_status); | |||
152 | struct reset_control *of_reset_control_get_by_index(struct device_node *node, | 149 | struct reset_control *of_reset_control_get_by_index(struct device_node *node, |
153 | int index) | 150 | int index) |
154 | { | 151 | { |
155 | struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); | 152 | struct reset_control *rstc; |
156 | struct reset_controller_dev *r, *rcdev; | 153 | struct reset_controller_dev *r, *rcdev; |
157 | struct of_phandle_args args; | 154 | struct of_phandle_args args; |
158 | int rstc_id; | 155 | int rstc_id; |
@@ -178,6 +175,11 @@ struct reset_control *of_reset_control_get_by_index(struct device_node *node, | |||
178 | return ERR_PTR(-EPROBE_DEFER); | 175 | return ERR_PTR(-EPROBE_DEFER); |
179 | } | 176 | } |
180 | 177 | ||
178 | if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) { | ||
179 | mutex_unlock(&reset_controller_list_mutex); | ||
180 | return ERR_PTR(-EINVAL); | ||
181 | } | ||
182 | |||
181 | rstc_id = rcdev->of_xlate(rcdev, &args); | 183 | rstc_id = rcdev->of_xlate(rcdev, &args); |
182 | if (rstc_id < 0) { | 184 | if (rstc_id < 0) { |
183 | mutex_unlock(&reset_controller_list_mutex); | 185 | mutex_unlock(&reset_controller_list_mutex); |
diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 7787a9b1cc67..8f55fd4a2630 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c | |||
@@ -57,7 +57,7 @@ static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev, | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | static struct reset_control_ops hi6220_reset_ops = { | 60 | static const struct reset_control_ops hi6220_reset_ops = { |
61 | .assert = hi6220_reset_assert, | 61 | .assert = hi6220_reset_assert, |
62 | .deassert = hi6220_reset_deassert, | 62 | .deassert = hi6220_reset_deassert, |
63 | }; | 63 | }; |
@@ -83,9 +83,7 @@ static int hi6220_reset_probe(struct platform_device *pdev) | |||
83 | data->rc_dev.ops = &hi6220_reset_ops; | 83 | data->rc_dev.ops = &hi6220_reset_ops; |
84 | data->rc_dev.of_node = pdev->dev.of_node; | 84 | data->rc_dev.of_node = pdev->dev.of_node; |
85 | 85 | ||
86 | reset_controller_register(&data->rc_dev); | 86 | return reset_controller_register(&data->rc_dev); |
87 | |||
88 | return 0; | ||
89 | } | 87 | } |
90 | 88 | ||
91 | static const struct of_device_id hi6220_reset_match[] = { | 89 | static const struct of_device_id hi6220_reset_match[] = { |
diff --git a/drivers/reset/reset-ath79.c b/drivers/reset/reset-ath79.c index 692fc890e94b..ccb940a8d9fb 100644 --- a/drivers/reset/reset-ath79.c +++ b/drivers/reset/reset-ath79.c | |||
@@ -70,7 +70,7 @@ static int ath79_reset_status(struct reset_controller_dev *rcdev, | |||
70 | return !!(val & BIT(id)); | 70 | return !!(val & BIT(id)); |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct reset_control_ops ath79_reset_ops = { | 73 | static const struct reset_control_ops ath79_reset_ops = { |
74 | .assert = ath79_reset_assert, | 74 | .assert = ath79_reset_assert, |
75 | .deassert = ath79_reset_deassert, | 75 | .deassert = ath79_reset_deassert, |
76 | .status = ath79_reset_status, | 76 | .status = ath79_reset_status, |
diff --git a/drivers/reset/reset-berlin.c b/drivers/reset/reset-berlin.c index 970b1ad60293..369f3917fd8e 100644 --- a/drivers/reset/reset-berlin.c +++ b/drivers/reset/reset-berlin.c | |||
@@ -46,7 +46,7 @@ static int berlin_reset_reset(struct reset_controller_dev *rcdev, | |||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | static struct reset_control_ops berlin_reset_ops = { | 49 | static const struct reset_control_ops berlin_reset_ops = { |
50 | .reset = berlin_reset_reset, | 50 | .reset = berlin_reset_reset, |
51 | }; | 51 | }; |
52 | 52 | ||
@@ -55,9 +55,6 @@ static int berlin_reset_xlate(struct reset_controller_dev *rcdev, | |||
55 | { | 55 | { |
56 | unsigned offset, bit; | 56 | unsigned offset, bit; |
57 | 57 | ||
58 | if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) | ||
59 | return -EINVAL; | ||
60 | |||
61 | offset = reset_spec->args[0]; | 58 | offset = reset_spec->args[0]; |
62 | bit = reset_spec->args[1]; | 59 | bit = reset_spec->args[1]; |
63 | 60 | ||
diff --git a/drivers/reset/reset-lpc18xx.c b/drivers/reset/reset-lpc18xx.c index 70922e9ac27f..3b8a4f5a1ff6 100644 --- a/drivers/reset/reset-lpc18xx.c +++ b/drivers/reset/reset-lpc18xx.c | |||
@@ -136,7 +136,7 @@ static int lpc18xx_rgu_status(struct reset_controller_dev *rcdev, | |||
136 | return !(readl(rc->base + offset) & bit); | 136 | return !(readl(rc->base + offset) & bit); |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct reset_control_ops lpc18xx_rgu_ops = { | 139 | static const struct reset_control_ops lpc18xx_rgu_ops = { |
140 | .reset = lpc18xx_rgu_reset, | 140 | .reset = lpc18xx_rgu_reset, |
141 | .assert = lpc18xx_rgu_assert, | 141 | .assert = lpc18xx_rgu_assert, |
142 | .deassert = lpc18xx_rgu_deassert, | 142 | .deassert = lpc18xx_rgu_deassert, |
diff --git a/drivers/reset/reset-pistachio.c b/drivers/reset/reset-pistachio.c new file mode 100644 index 000000000000..72a97a15a4c8 --- /dev/null +++ b/drivers/reset/reset-pistachio.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* | ||
2 | * Pistachio SoC Reset Controller driver | ||
3 | * | ||
4 | * Copyright (C) 2015 Imagination Technologies Ltd. | ||
5 | * | ||
6 | * Author: Damien Horsley <Damien.Horsley@imgtec.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/regmap.h> | ||
17 | #include <linux/reset-controller.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/mfd/syscon.h> | ||
20 | |||
21 | #include <dt-bindings/reset/pistachio-resets.h> | ||
22 | |||
23 | #define PISTACHIO_SOFT_RESET 0 | ||
24 | |||
25 | struct pistachio_reset_data { | ||
26 | struct reset_controller_dev rcdev; | ||
27 | struct regmap *periph_regs; | ||
28 | }; | ||
29 | |||
30 | static inline int pistachio_reset_shift(unsigned long id) | ||
31 | { | ||
32 | switch (id) { | ||
33 | case PISTACHIO_RESET_I2C0: | ||
34 | case PISTACHIO_RESET_I2C1: | ||
35 | case PISTACHIO_RESET_I2C2: | ||
36 | case PISTACHIO_RESET_I2C3: | ||
37 | case PISTACHIO_RESET_I2S_IN: | ||
38 | case PISTACHIO_RESET_PRL_OUT: | ||
39 | case PISTACHIO_RESET_SPDIF_OUT: | ||
40 | case PISTACHIO_RESET_SPI: | ||
41 | case PISTACHIO_RESET_PWM_PDM: | ||
42 | case PISTACHIO_RESET_UART0: | ||
43 | case PISTACHIO_RESET_UART1: | ||
44 | case PISTACHIO_RESET_QSPI: | ||
45 | case PISTACHIO_RESET_MDC: | ||
46 | case PISTACHIO_RESET_SDHOST: | ||
47 | case PISTACHIO_RESET_ETHERNET: | ||
48 | case PISTACHIO_RESET_IR: | ||
49 | case PISTACHIO_RESET_HASH: | ||
50 | case PISTACHIO_RESET_TIMER: | ||
51 | return id; | ||
52 | case PISTACHIO_RESET_I2S_OUT: | ||
53 | case PISTACHIO_RESET_SPDIF_IN: | ||
54 | case PISTACHIO_RESET_EVT: | ||
55 | return id + 6; | ||
56 | case PISTACHIO_RESET_USB_H: | ||
57 | case PISTACHIO_RESET_USB_PR: | ||
58 | case PISTACHIO_RESET_USB_PHY_PR: | ||
59 | case PISTACHIO_RESET_USB_PHY_PON: | ||
60 | return id + 7; | ||
61 | default: | ||
62 | return -EINVAL; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | static int pistachio_reset_assert(struct reset_controller_dev *rcdev, | ||
67 | unsigned long id) | ||
68 | { | ||
69 | struct pistachio_reset_data *rd; | ||
70 | u32 mask; | ||
71 | int shift; | ||
72 | |||
73 | rd = container_of(rcdev, struct pistachio_reset_data, rcdev); | ||
74 | shift = pistachio_reset_shift(id); | ||
75 | if (shift < 0) | ||
76 | return shift; | ||
77 | mask = BIT(shift); | ||
78 | |||
79 | return regmap_update_bits(rd->periph_regs, PISTACHIO_SOFT_RESET, | ||
80 | mask, mask); | ||
81 | } | ||
82 | |||
83 | static int pistachio_reset_deassert(struct reset_controller_dev *rcdev, | ||
84 | unsigned long id) | ||
85 | { | ||
86 | struct pistachio_reset_data *rd; | ||
87 | u32 mask; | ||
88 | int shift; | ||
89 | |||
90 | rd = container_of(rcdev, struct pistachio_reset_data, rcdev); | ||
91 | shift = pistachio_reset_shift(id); | ||
92 | if (shift < 0) | ||
93 | return shift; | ||
94 | mask = BIT(shift); | ||
95 | |||
96 | return regmap_update_bits(rd->periph_regs, PISTACHIO_SOFT_RESET, | ||
97 | mask, 0); | ||
98 | } | ||
99 | |||
100 | static const struct reset_control_ops pistachio_reset_ops = { | ||
101 | .assert = pistachio_reset_assert, | ||
102 | .deassert = pistachio_reset_deassert, | ||
103 | }; | ||
104 | |||
105 | static int pistachio_reset_probe(struct platform_device *pdev) | ||
106 | { | ||
107 | struct pistachio_reset_data *rd; | ||
108 | struct device *dev = &pdev->dev; | ||
109 | struct device_node *np = pdev->dev.of_node; | ||
110 | |||
111 | rd = devm_kzalloc(dev, sizeof(*rd), GFP_KERNEL); | ||
112 | if (!rd) | ||
113 | return -ENOMEM; | ||
114 | |||
115 | rd->periph_regs = syscon_node_to_regmap(np->parent); | ||
116 | if (IS_ERR(rd->periph_regs)) | ||
117 | return PTR_ERR(rd->periph_regs); | ||
118 | |||
119 | rd->rcdev.owner = THIS_MODULE; | ||
120 | rd->rcdev.nr_resets = PISTACHIO_RESET_MAX + 1; | ||
121 | rd->rcdev.ops = &pistachio_reset_ops; | ||
122 | rd->rcdev.of_node = np; | ||
123 | |||
124 | return reset_controller_register(&rd->rcdev); | ||
125 | } | ||
126 | |||
127 | static int pistachio_reset_remove(struct platform_device *pdev) | ||
128 | { | ||
129 | struct pistachio_reset_data *data = platform_get_drvdata(pdev); | ||
130 | |||
131 | reset_controller_unregister(&data->rcdev); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static const struct of_device_id pistachio_reset_dt_ids[] = { | ||
137 | { .compatible = "img,pistachio-reset", }, | ||
138 | { /* sentinel */ }, | ||
139 | }; | ||
140 | MODULE_DEVICE_TABLE(of, pistachio_reset_dt_ids); | ||
141 | |||
142 | static struct platform_driver pistachio_reset_driver = { | ||
143 | .probe = pistachio_reset_probe, | ||
144 | .remove = pistachio_reset_remove, | ||
145 | .driver = { | ||
146 | .name = "pistachio-reset", | ||
147 | .of_match_table = pistachio_reset_dt_ids, | ||
148 | }, | ||
149 | }; | ||
150 | module_platform_driver(pistachio_reset_driver); | ||
151 | |||
152 | MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>"); | ||
153 | MODULE_DESCRIPTION("Pistacho Reset Controller Driver"); | ||
154 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index b7d773d9248c..cd05a7032b17 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c | |||
@@ -90,7 +90,7 @@ static int socfpga_reset_status(struct reset_controller_dev *rcdev, | |||
90 | return !(reg & BIT(offset)); | 90 | return !(reg & BIT(offset)); |
91 | } | 91 | } |
92 | 92 | ||
93 | static struct reset_control_ops socfpga_reset_ops = { | 93 | static const struct reset_control_ops socfpga_reset_ops = { |
94 | .assert = socfpga_reset_assert, | 94 | .assert = socfpga_reset_assert, |
95 | .deassert = socfpga_reset_deassert, | 95 | .deassert = socfpga_reset_deassert, |
96 | .status = socfpga_reset_status, | 96 | .status = socfpga_reset_status, |
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index 8d41a18da17f..677f86555212 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c | |||
@@ -70,7 +70,7 @@ static int sunxi_reset_deassert(struct reset_controller_dev *rcdev, | |||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct reset_control_ops sunxi_reset_ops = { | 73 | static const struct reset_control_ops sunxi_reset_ops = { |
74 | .assert = sunxi_reset_assert, | 74 | .assert = sunxi_reset_assert, |
75 | .deassert = sunxi_reset_deassert, | 75 | .deassert = sunxi_reset_deassert, |
76 | }; | 76 | }; |
diff --git a/drivers/reset/reset-zynq.c b/drivers/reset/reset-zynq.c index c6b3cd8b40ad..a7e87bc45885 100644 --- a/drivers/reset/reset-zynq.c +++ b/drivers/reset/reset-zynq.c | |||
@@ -86,7 +86,7 @@ static int zynq_reset_status(struct reset_controller_dev *rcdev, | |||
86 | return !!(reg & BIT(offset)); | 86 | return !!(reg & BIT(offset)); |
87 | } | 87 | } |
88 | 88 | ||
89 | static struct reset_control_ops zynq_reset_ops = { | 89 | static const struct reset_control_ops zynq_reset_ops = { |
90 | .assert = zynq_reset_assert, | 90 | .assert = zynq_reset_assert, |
91 | .deassert = zynq_reset_deassert, | 91 | .deassert = zynq_reset_deassert, |
92 | .status = zynq_reset_status, | 92 | .status = zynq_reset_status, |
diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c index 1600cc7557f5..9bd57a5eee72 100644 --- a/drivers/reset/sti/reset-syscfg.c +++ b/drivers/reset/sti/reset-syscfg.c | |||
@@ -134,7 +134,7 @@ static int syscfg_reset_status(struct reset_controller_dev *rcdev, | |||
134 | return rst->active_low ? !ret_val : !!ret_val; | 134 | return rst->active_low ? !ret_val : !!ret_val; |
135 | } | 135 | } |
136 | 136 | ||
137 | static struct reset_control_ops syscfg_reset_ops = { | 137 | static const struct reset_control_ops syscfg_reset_ops = { |
138 | .reset = syscfg_reset_dev, | 138 | .reset = syscfg_reset_dev, |
139 | .assert = syscfg_reset_assert, | 139 | .assert = syscfg_reset_assert, |
140 | .deassert = syscfg_reset_deassert, | 140 | .deassert = syscfg_reset_deassert, |
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 534c58937a56..43155e1f97b9 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/regmap.h> | 18 | #include <linux/regmap.h> |
19 | #include <linux/mfd/syscon.h> | 19 | #include <linux/mfd/syscon.h> |
20 | #include <dt-bindings/power/rk3288-power.h> | 20 | #include <dt-bindings/power/rk3288-power.h> |
21 | #include <dt-bindings/power/rk3368-power.h> | ||
21 | 22 | ||
22 | struct rockchip_domain_info { | 23 | struct rockchip_domain_info { |
23 | int pwr_mask; | 24 | int pwr_mask; |
@@ -75,6 +76,9 @@ struct rockchip_pmu { | |||
75 | #define DOMAIN_RK3288(pwr, status, req) \ | 76 | #define DOMAIN_RK3288(pwr, status, req) \ |
76 | DOMAIN(pwr, status, req, req, (req) + 16) | 77 | DOMAIN(pwr, status, req, req, (req) + 16) |
77 | 78 | ||
79 | #define DOMAIN_RK3368(pwr, status, req) \ | ||
80 | DOMAIN(pwr, status, req, (req) + 16, req) | ||
81 | |||
78 | static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) | 82 | static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) |
79 | { | 83 | { |
80 | struct rockchip_pmu *pmu = pd->pmu; | 84 | struct rockchip_pmu *pmu = pd->pmu; |
@@ -419,6 +423,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) | |||
419 | if (error) { | 423 | if (error) { |
420 | dev_err(dev, "failed to handle node %s: %d\n", | 424 | dev_err(dev, "failed to handle node %s: %d\n", |
421 | node->name, error); | 425 | node->name, error); |
426 | of_node_put(node); | ||
422 | goto err_out; | 427 | goto err_out; |
423 | } | 428 | } |
424 | } | 429 | } |
@@ -444,6 +449,14 @@ static const struct rockchip_domain_info rk3288_pm_domains[] = { | |||
444 | [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2), | 449 | [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2), |
445 | }; | 450 | }; |
446 | 451 | ||
452 | static const struct rockchip_domain_info rk3368_pm_domains[] = { | ||
453 | [RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6), | ||
454 | [RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8), | ||
455 | [RK3368_PD_VIDEO] = DOMAIN_RK3368(14, 13, 7), | ||
456 | [RK3368_PD_GPU_0] = DOMAIN_RK3368(16, 15, 2), | ||
457 | [RK3368_PD_GPU_1] = DOMAIN_RK3368(17, 16, 2), | ||
458 | }; | ||
459 | |||
447 | static const struct rockchip_pmu_info rk3288_pmu = { | 460 | static const struct rockchip_pmu_info rk3288_pmu = { |
448 | .pwr_offset = 0x08, | 461 | .pwr_offset = 0x08, |
449 | .status_offset = 0x0c, | 462 | .status_offset = 0x0c, |
@@ -461,11 +474,32 @@ static const struct rockchip_pmu_info rk3288_pmu = { | |||
461 | .domain_info = rk3288_pm_domains, | 474 | .domain_info = rk3288_pm_domains, |
462 | }; | 475 | }; |
463 | 476 | ||
477 | static const struct rockchip_pmu_info rk3368_pmu = { | ||
478 | .pwr_offset = 0x0c, | ||
479 | .status_offset = 0x10, | ||
480 | .req_offset = 0x3c, | ||
481 | .idle_offset = 0x40, | ||
482 | .ack_offset = 0x40, | ||
483 | |||
484 | .core_pwrcnt_offset = 0x48, | ||
485 | .gpu_pwrcnt_offset = 0x50, | ||
486 | |||
487 | .core_power_transition_time = 24, | ||
488 | .gpu_power_transition_time = 24, | ||
489 | |||
490 | .num_domains = ARRAY_SIZE(rk3368_pm_domains), | ||
491 | .domain_info = rk3368_pm_domains, | ||
492 | }; | ||
493 | |||
464 | static const struct of_device_id rockchip_pm_domain_dt_match[] = { | 494 | static const struct of_device_id rockchip_pm_domain_dt_match[] = { |
465 | { | 495 | { |
466 | .compatible = "rockchip,rk3288-power-controller", | 496 | .compatible = "rockchip,rk3288-power-controller", |
467 | .data = (void *)&rk3288_pmu, | 497 | .data = (void *)&rk3288_pmu, |
468 | }, | 498 | }, |
499 | { | ||
500 | .compatible = "rockchip,rk3368-power-controller", | ||
501 | .data = (void *)&rk3368_pmu, | ||
502 | }, | ||
469 | { /* sentinel */ }, | 503 | { /* sentinel */ }, |
470 | }; | 504 | }; |
471 | 505 | ||
diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index bc52670c8f4b..99e354c8f53f 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c | |||
@@ -117,7 +117,7 @@ static int sunxi_sram_show(struct seq_file *s, void *data) | |||
117 | 117 | ||
118 | val = readl(base + sram_data->reg); | 118 | val = readl(base + sram_data->reg); |
119 | val >>= sram_data->offset; | 119 | val >>= sram_data->offset; |
120 | val &= sram_data->width; | 120 | val &= GENMASK(sram_data->width - 1, 0); |
121 | 121 | ||
122 | for (func = sram_data->func; func->func; func++) { | 122 | for (func = sram_data->func; func->func; func++) { |
123 | seq_printf(s, "\t\t%s%c\n", func->func, | 123 | seq_printf(s, "\t\t%s%c\n", func->func, |
@@ -208,7 +208,8 @@ int sunxi_sram_claim(struct device *dev) | |||
208 | return -EBUSY; | 208 | return -EBUSY; |
209 | } | 209 | } |
210 | 210 | ||
211 | mask = GENMASK(sram_data->offset + sram_data->width, sram_data->offset); | 211 | mask = GENMASK(sram_data->offset + sram_data->width - 1, |
212 | sram_data->offset); | ||
212 | val = readl(base + sram_data->reg); | 213 | val = readl(base + sram_data->reg); |
213 | val &= ~mask; | 214 | val &= ~mask; |
214 | writel(val | ((device << sram_data->offset) & mask), | 215 | writel(val | ((device << sram_data->offset) & mask), |
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index dbde1149c218..81d42cce885a 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
@@ -17,7 +17,9 @@ | |||
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/mfd/syscon.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/regmap.h> | ||
21 | #include <linux/usb/ch9.h> | 23 | #include <linux/usb/ch9.h> |
22 | #include <linux/usb/gadget.h> | 24 | #include <linux/usb/gadget.h> |
23 | #include <linux/usb/atmel_usba_udc.h> | 25 | #include <linux/usb/atmel_usba_udc.h> |
@@ -1886,20 +1888,15 @@ static int atmel_usba_stop(struct usb_gadget *gadget) | |||
1886 | #ifdef CONFIG_OF | 1888 | #ifdef CONFIG_OF |
1887 | static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on) | 1889 | static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on) |
1888 | { | 1890 | { |
1889 | unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); | 1891 | regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN, |
1890 | 1892 | is_on ? AT91_PMC_BIASEN : 0); | |
1891 | if (is_on) | ||
1892 | at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); | ||
1893 | else | ||
1894 | at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); | ||
1895 | } | 1893 | } |
1896 | 1894 | ||
1897 | static void at91sam9g45_pulse_bias(struct usba_udc *udc) | 1895 | static void at91sam9g45_pulse_bias(struct usba_udc *udc) |
1898 | { | 1896 | { |
1899 | unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); | 1897 | regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN, 0); |
1900 | 1898 | regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN, | |
1901 | at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); | 1899 | AT91_PMC_BIASEN); |
1902 | at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); | ||
1903 | } | 1900 | } |
1904 | 1901 | ||
1905 | static const struct usba_udc_errata at91sam9rl_errata = { | 1902 | static const struct usba_udc_errata at91sam9rl_errata = { |
@@ -1936,6 +1933,9 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, | |||
1936 | return ERR_PTR(-EINVAL); | 1933 | return ERR_PTR(-EINVAL); |
1937 | 1934 | ||
1938 | udc->errata = match->data; | 1935 | udc->errata = match->data; |
1936 | udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9g45-pmc"); | ||
1937 | if (udc->errata && IS_ERR(udc->pmc)) | ||
1938 | return ERR_CAST(udc->pmc); | ||
1939 | 1939 | ||
1940 | udc->num_ep = 0; | 1940 | udc->num_ep = 0; |
1941 | 1941 | ||
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index ea448a344767..3e1c9d589dfa 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h | |||
@@ -354,6 +354,8 @@ struct usba_udc { | |||
354 | struct dentry *debugfs_root; | 354 | struct dentry *debugfs_root; |
355 | struct dentry *debugfs_regs; | 355 | struct dentry *debugfs_regs; |
356 | #endif | 356 | #endif |
357 | |||
358 | struct regmap *pmc; | ||
357 | }; | 359 | }; |
358 | 360 | ||
359 | static inline struct usba_ep *to_usba_ep(struct usb_ep *ep) | 361 | static inline struct usba_ep *to_usba_ep(struct usb_ep *ep) |
diff --git a/include/dt-bindings/power/rk3368-power.h b/include/dt-bindings/power/rk3368-power.h new file mode 100644 index 000000000000..93633d57ed84 --- /dev/null +++ b/include/dt-bindings/power/rk3368-power.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef __DT_BINDINGS_POWER_RK3368_POWER_H__ | ||
2 | #define __DT_BINDINGS_POWER_RK3368_POWER_H__ | ||
3 | |||
4 | /* VD_CORE */ | ||
5 | #define RK3368_PD_A53_L0 0 | ||
6 | #define RK3368_PD_A53_L1 1 | ||
7 | #define RK3368_PD_A53_L2 2 | ||
8 | #define RK3368_PD_A53_L3 3 | ||
9 | #define RK3368_PD_SCU_L 4 | ||
10 | #define RK3368_PD_A53_B0 5 | ||
11 | #define RK3368_PD_A53_B1 6 | ||
12 | #define RK3368_PD_A53_B2 7 | ||
13 | #define RK3368_PD_A53_B3 8 | ||
14 | #define RK3368_PD_SCU_B 9 | ||
15 | |||
16 | /* VD_LOGIC */ | ||
17 | #define RK3368_PD_BUS 10 | ||
18 | #define RK3368_PD_PERI 11 | ||
19 | #define RK3368_PD_VIO 12 | ||
20 | #define RK3368_PD_ALIVE 13 | ||
21 | #define RK3368_PD_VIDEO 14 | ||
22 | #define RK3368_PD_GPU_0 15 | ||
23 | #define RK3368_PD_GPU_1 16 | ||
24 | |||
25 | /* VD_PMU */ | ||
26 | #define RK3368_PD_PMU 17 | ||
27 | |||
28 | #endif | ||
diff --git a/include/dt-bindings/reset/pistachio-resets.h b/include/dt-bindings/reset/pistachio-resets.h new file mode 100644 index 000000000000..60a189b1faef --- /dev/null +++ b/include/dt-bindings/reset/pistachio-resets.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * This header provides constants for the reset controller | ||
3 | * present in the Pistachio SoC | ||
4 | */ | ||
5 | |||
6 | #ifndef _PISTACHIO_RESETS_H | ||
7 | #define _PISTACHIO_RESETS_H | ||
8 | |||
9 | #define PISTACHIO_RESET_I2C0 0 | ||
10 | #define PISTACHIO_RESET_I2C1 1 | ||
11 | #define PISTACHIO_RESET_I2C2 2 | ||
12 | #define PISTACHIO_RESET_I2C3 3 | ||
13 | #define PISTACHIO_RESET_I2S_IN 4 | ||
14 | #define PISTACHIO_RESET_PRL_OUT 5 | ||
15 | #define PISTACHIO_RESET_SPDIF_OUT 6 | ||
16 | #define PISTACHIO_RESET_SPI 7 | ||
17 | #define PISTACHIO_RESET_PWM_PDM 8 | ||
18 | #define PISTACHIO_RESET_UART0 9 | ||
19 | #define PISTACHIO_RESET_UART1 10 | ||
20 | #define PISTACHIO_RESET_QSPI 11 | ||
21 | #define PISTACHIO_RESET_MDC 12 | ||
22 | #define PISTACHIO_RESET_SDHOST 13 | ||
23 | #define PISTACHIO_RESET_ETHERNET 14 | ||
24 | #define PISTACHIO_RESET_IR 15 | ||
25 | #define PISTACHIO_RESET_HASH 16 | ||
26 | #define PISTACHIO_RESET_TIMER 17 | ||
27 | #define PISTACHIO_RESET_I2S_OUT 18 | ||
28 | #define PISTACHIO_RESET_SPDIF_IN 19 | ||
29 | #define PISTACHIO_RESET_EVT 20 | ||
30 | #define PISTACHIO_RESET_USB_H 21 | ||
31 | #define PISTACHIO_RESET_USB_PR 22 | ||
32 | #define PISTACHIO_RESET_USB_PHY_PR 23 | ||
33 | #define PISTACHIO_RESET_USB_PHY_PON 24 | ||
34 | #define PISTACHIO_RESET_MAX 24 | ||
35 | |||
36 | #endif | ||
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index 1e6932222e11..17f413bbbedf 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h | |||
@@ -16,18 +16,6 @@ | |||
16 | #ifndef AT91_PMC_H | 16 | #ifndef AT91_PMC_H |
17 | #define AT91_PMC_H | 17 | #define AT91_PMC_H |
18 | 18 | ||
19 | #ifndef __ASSEMBLY__ | ||
20 | extern void __iomem *at91_pmc_base; | ||
21 | |||
22 | #define at91_pmc_read(field) \ | ||
23 | readl_relaxed(at91_pmc_base + field) | ||
24 | |||
25 | #define at91_pmc_write(field, value) \ | ||
26 | writel_relaxed(value, at91_pmc_base + field) | ||
27 | #else | ||
28 | .extern at91_pmc_base | ||
29 | #endif | ||
30 | |||
31 | #define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ | 19 | #define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ |
32 | #define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */ | 20 | #define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */ |
33 | 21 | ||
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h index 7dee00143afd..d833eb4dd446 100644 --- a/include/linux/omap-gpmc.h +++ b/include/linux/omap-gpmc.h | |||
@@ -51,6 +51,9 @@ struct gpmc_timings { | |||
51 | u32 adv_on; /* Assertion time */ | 51 | u32 adv_on; /* Assertion time */ |
52 | u32 adv_rd_off; /* Read deassertion time */ | 52 | u32 adv_rd_off; /* Read deassertion time */ |
53 | u32 adv_wr_off; /* Write deassertion time */ | 53 | u32 adv_wr_off; /* Write deassertion time */ |
54 | u32 adv_aad_mux_on; /* ADV assertion time for AAD */ | ||
55 | u32 adv_aad_mux_rd_off; /* ADV read deassertion time for AAD */ | ||
56 | u32 adv_aad_mux_wr_off; /* ADV write deassertion time for AAD */ | ||
54 | 57 | ||
55 | /* WE signals timings corresponding to GPMC_CONFIG4 */ | 58 | /* WE signals timings corresponding to GPMC_CONFIG4 */ |
56 | u32 we_on; /* WE assertion time */ | 59 | u32 we_on; /* WE assertion time */ |
@@ -59,6 +62,8 @@ struct gpmc_timings { | |||
59 | /* OE signals timings corresponding to GPMC_CONFIG4 */ | 62 | /* OE signals timings corresponding to GPMC_CONFIG4 */ |
60 | u32 oe_on; /* OE assertion time */ | 63 | u32 oe_on; /* OE assertion time */ |
61 | u32 oe_off; /* OE deassertion time */ | 64 | u32 oe_off; /* OE deassertion time */ |
65 | u32 oe_aad_mux_on; /* OE assertion time for AAD */ | ||
66 | u32 oe_aad_mux_off; /* OE deassertion time for AAD */ | ||
62 | 67 | ||
63 | /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */ | 68 | /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */ |
64 | u32 page_burst_access; /* Multiple access word delay */ | 69 | u32 page_burst_access; /* Multiple access word delay */ |
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index ce6b962ffed4..a3a5bcdb1d02 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h | |||
@@ -38,7 +38,7 @@ struct of_phandle_args; | |||
38 | * @nr_resets: number of reset controls in this reset controller device | 38 | * @nr_resets: number of reset controls in this reset controller device |
39 | */ | 39 | */ |
40 | struct reset_controller_dev { | 40 | struct reset_controller_dev { |
41 | struct reset_control_ops *ops; | 41 | const struct reset_control_ops *ops; |
42 | struct module *owner; | 42 | struct module *owner; |
43 | struct list_head list; | 43 | struct list_head list; |
44 | struct device_node *of_node; | 44 | struct device_node *of_node; |
diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h index 72ce932c69b2..35de50a65665 100644 --- a/include/linux/scpi_protocol.h +++ b/include/linux/scpi_protocol.h | |||
@@ -33,6 +33,7 @@ enum scpi_sensor_class { | |||
33 | VOLTAGE, | 33 | VOLTAGE, |
34 | CURRENT, | 34 | CURRENT, |
35 | POWER, | 35 | POWER, |
36 | ENERGY, | ||
36 | }; | 37 | }; |
37 | 38 | ||
38 | struct scpi_sensor_info { | 39 | struct scpi_sensor_info { |
@@ -68,7 +69,7 @@ struct scpi_ops { | |||
68 | struct scpi_dvfs_info *(*dvfs_get_info)(u8); | 69 | struct scpi_dvfs_info *(*dvfs_get_info)(u8); |
69 | int (*sensor_get_capability)(u16 *sensors); | 70 | int (*sensor_get_capability)(u16 *sensors); |
70 | int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *); | 71 | int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *); |
71 | int (*sensor_get_value)(u16, u32 *); | 72 | int (*sensor_get_value)(u16, u64 *); |
72 | }; | 73 | }; |
73 | 74 | ||
74 | #if IS_REACHABLE(CONFIG_ARM_SCPI_PROTOCOL) | 75 | #if IS_REACHABLE(CONFIG_ARM_SCPI_PROTOCOL) |