diff options
107 files changed, 5490 insertions, 699 deletions
diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt index bae0d87a38b2..5573c08d3180 100644 --- a/Documentation/devicetree/bindings/arm/gic.txt +++ b/Documentation/devicetree/bindings/arm/gic.txt | |||
@@ -50,6 +50,11 @@ Optional | |||
50 | regions, used when the GIC doesn't have banked registers. The offset is | 50 | regions, used when the GIC doesn't have banked registers. The offset is |
51 | cpu-offset * cpu-nr. | 51 | cpu-offset * cpu-nr. |
52 | 52 | ||
53 | - arm,routable-irqs : Total number of gic irq inputs which are not directly | ||
54 | connected from the peripherals, but are routed dynamically | ||
55 | by a crossbar/multiplexer preceding the GIC. The GIC irq | ||
56 | input line is assigned dynamically when the corresponding | ||
57 | peripheral's crossbar line is mapped. | ||
53 | Example: | 58 | Example: |
54 | 59 | ||
55 | intc: interrupt-controller@fff11000 { | 60 | intc: interrupt-controller@fff11000 { |
@@ -57,6 +62,7 @@ Example: | |||
57 | #interrupt-cells = <3>; | 62 | #interrupt-cells = <3>; |
58 | #address-cells = <1>; | 63 | #address-cells = <1>; |
59 | interrupt-controller; | 64 | interrupt-controller; |
65 | arm,routable-irqs = <160>; | ||
60 | reg = <0xfff11000 0x1000>, | 66 | reg = <0xfff11000 0x1000>, |
61 | <0xfff10100 0x100>; | 67 | <0xfff10100 0x100>; |
62 | }; | 68 | }; |
diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt b/Documentation/devicetree/bindings/arm/omap/crossbar.txt new file mode 100644 index 000000000000..fb88585cfb93 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | Some socs have a large number of interrupts requests to service | ||
2 | the needs of its many peripherals and subsystems. All of the | ||
3 | interrupt lines from the subsystems are not needed at the same | ||
4 | time, so they have to be muxed to the irq-controller appropriately. | ||
5 | In such places a interrupt controllers are preceded by an CROSSBAR | ||
6 | that provides flexibility in muxing the device requests to the controller | ||
7 | inputs. | ||
8 | |||
9 | Required properties: | ||
10 | - compatible : Should be "ti,irq-crossbar" | ||
11 | - reg: Base address and the size of the crossbar registers. | ||
12 | - ti,max-irqs: Total number of irqs available at the interrupt controller. | ||
13 | - ti,reg-size: Size of a individual register in bytes. Every individual | ||
14 | register is assumed to be of same size. Valid sizes are 1, 2, 4. | ||
15 | - ti,irqs-reserved: List of the reserved irq lines that are not muxed using | ||
16 | crossbar. These interrupt lines are reserved in the soc, | ||
17 | so crossbar bar driver should not consider them as free | ||
18 | lines. | ||
19 | |||
20 | Examples: | ||
21 | crossbar_mpu: @4a020000 { | ||
22 | compatible = "ti,irq-crossbar"; | ||
23 | reg = <0x4a002a48 0x130>; | ||
24 | ti,max-irqs = <160>; | ||
25 | ti,reg-size = <2>; | ||
26 | ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>; | ||
27 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/arm-integrator.txt b/Documentation/devicetree/bindings/clock/arm-integrator.txt new file mode 100644 index 000000000000..652914b17b95 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/arm-integrator.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | Clock bindings for ARM Integrator Core Module clocks | ||
2 | |||
3 | Auxilary Oscillator Clock | ||
4 | |||
5 | This is a configurable clock fed from a 24 MHz chrystal, | ||
6 | used for generating e.g. video clocks. It is located on the | ||
7 | core module and there is only one of these. | ||
8 | |||
9 | This clock node *must* be a subnode of the core module, since | ||
10 | it obtains the base address for it's address range from its | ||
11 | parent node. | ||
12 | |||
13 | |||
14 | Required properties: | ||
15 | - compatible: must be "arm,integrator-cm-auxosc" | ||
16 | - #clock-cells: must be <0> | ||
17 | |||
18 | Optional properties: | ||
19 | - clocks: parent clock(s) | ||
20 | |||
21 | Example: | ||
22 | |||
23 | core-module@10000000 { | ||
24 | xtal24mhz: xtal24mhz@24M { | ||
25 | #clock-cells = <0>; | ||
26 | compatible = "fixed-clock"; | ||
27 | clock-frequency = <24000000>; | ||
28 | }; | ||
29 | auxosc: cm_aux_osc@25M { | ||
30 | #clock-cells = <0>; | ||
31 | compatible = "arm,integrator-cm-auxosc"; | ||
32 | clocks = <&xtal24mhz>; | ||
33 | }; | ||
34 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt new file mode 100644 index 000000000000..4897bea7e3f8 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | * Altera SOCFPGA specific extensions to the Synopsys Designware Mobile | ||
2 | Storage Host Controller | ||
3 | |||
4 | The Synopsys designware mobile storage host controller is used to interface | ||
5 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents | ||
6 | differences between the core Synopsys dw mshc controller properties described | ||
7 | by synopsys-dw-mshc.txt and the properties used by the Altera SOCFPGA specific | ||
8 | extensions to the Synopsys Designware Mobile Storage Host Controller. | ||
9 | |||
10 | Required Properties: | ||
11 | |||
12 | * compatible: should be | ||
13 | - "altr,socfpga-dw-mshc": for Altera's SOCFPGA platform | ||
14 | |||
15 | Example: | ||
16 | |||
17 | mmc: dwmmc0@ff704000 { | ||
18 | compatible = "altr,socfpga-dw-mshc"; | ||
19 | reg = <0xff704000 0x1000>; | ||
20 | interrupts = <0 129 4>; | ||
21 | #address-cells = <1>; | ||
22 | #size-cells = <0>; | ||
23 | }; | ||
diff --git a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt index 0347d8350d94..af25e77c0e0c 100644 --- a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt +++ b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt | |||
@@ -6,8 +6,11 @@ Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the | |||
6 | microcontroller to turn the power off. This driver adds a handler to | 6 | microcontroller to turn the power off. This driver adds a handler to |
7 | pm_power_off which is called to turn the power off. | 7 | pm_power_off which is called to turn the power off. |
8 | 8 | ||
9 | Synology NAS devices use a similar scheme, but a different baud rate, | ||
10 | 9600, and a different character, '1'. | ||
11 | |||
9 | Required Properties: | 12 | Required Properties: |
10 | - compatible: Should be "qnap,power-off" | 13 | - compatible: Should be "qnap,power-off" or "synology,power-off" |
11 | 14 | ||
12 | - reg: Address and length of the register set for UART1 | 15 | - reg: Address and length of the register set for UART1 |
13 | - clocks: tclk clock | 16 | - clocks: tclk clock |
diff --git a/Documentation/devicetree/bindings/watchdog/marvel.txt b/Documentation/devicetree/bindings/watchdog/marvel.txt index 5dc8d30061ce..de11eb4c121f 100644 --- a/Documentation/devicetree/bindings/watchdog/marvel.txt +++ b/Documentation/devicetree/bindings/watchdog/marvel.txt | |||
@@ -3,17 +3,24 @@ | |||
3 | Required Properties: | 3 | Required Properties: |
4 | 4 | ||
5 | - Compatibility : "marvell,orion-wdt" | 5 | - Compatibility : "marvell,orion-wdt" |
6 | - reg : Address of the timer registers | 6 | "marvell,armada-370-wdt" |
7 | "marvell,armada-xp-wdt" | ||
8 | |||
9 | - reg : Should contain two entries: first one with the | ||
10 | timer control address, second one with the | ||
11 | rstout enable address. | ||
7 | 12 | ||
8 | Optional properties: | 13 | Optional properties: |
9 | 14 | ||
15 | - interrupts : Contains the IRQ for watchdog expiration | ||
10 | - timeout-sec : Contains the watchdog timeout in seconds | 16 | - timeout-sec : Contains the watchdog timeout in seconds |
11 | 17 | ||
12 | Example: | 18 | Example: |
13 | 19 | ||
14 | wdt@20300 { | 20 | wdt@20300 { |
15 | compatible = "marvell,orion-wdt"; | 21 | compatible = "marvell,orion-wdt"; |
16 | reg = <0x20300 0x28>; | 22 | reg = <0x20300 0x28>, <0x20108 0x4>; |
23 | interrupts = <3>; | ||
17 | timeout-sec = <10>; | 24 | timeout-sec = <10>; |
18 | status = "okay"; | 25 | status = "okay"; |
19 | }; | 26 | }; |
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index e6be9315ff0a..b10e6351da53 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts | |||
@@ -18,6 +18,28 @@ | |||
18 | bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; | 18 | bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; |
19 | }; | 19 | }; |
20 | 20 | ||
21 | /* 24 MHz chrystal on the core module */ | ||
22 | xtal24mhz: xtal24mhz@24M { | ||
23 | #clock-cells = <0>; | ||
24 | compatible = "fixed-clock"; | ||
25 | clock-frequency = <24000000>; | ||
26 | }; | ||
27 | |||
28 | pclk: pclk@0 { | ||
29 | #clock-cells = <0>; | ||
30 | compatible = "fixed-factor-clock"; | ||
31 | clock-div = <1>; | ||
32 | clock-mult = <1>; | ||
33 | clocks = <&xtal24mhz>; | ||
34 | }; | ||
35 | |||
36 | /* The UART clock is 14.74 MHz divided by an ICS525 */ | ||
37 | uartclk: uartclk@14.74M { | ||
38 | #clock-cells = <0>; | ||
39 | compatible = "fixed-clock"; | ||
40 | clock-frequency = <14745600>; | ||
41 | }; | ||
42 | |||
21 | syscon { | 43 | syscon { |
22 | compatible = "arm,integrator-ap-syscon"; | 44 | compatible = "arm,integrator-ap-syscon"; |
23 | reg = <0x11000000 0x100>; | 45 | reg = <0x11000000 0x100>; |
@@ -28,14 +50,17 @@ | |||
28 | 50 | ||
29 | timer0: timer@13000000 { | 51 | timer0: timer@13000000 { |
30 | compatible = "arm,integrator-timer"; | 52 | compatible = "arm,integrator-timer"; |
53 | clocks = <&xtal24mhz>; | ||
31 | }; | 54 | }; |
32 | 55 | ||
33 | timer1: timer@13000100 { | 56 | timer1: timer@13000100 { |
34 | compatible = "arm,integrator-timer"; | 57 | compatible = "arm,integrator-timer"; |
58 | clocks = <&xtal24mhz>; | ||
35 | }; | 59 | }; |
36 | 60 | ||
37 | timer2: timer@13000200 { | 61 | timer2: timer@13000200 { |
38 | compatible = "arm,integrator-timer"; | 62 | compatible = "arm,integrator-timer"; |
63 | clocks = <&xtal24mhz>; | ||
39 | }; | 64 | }; |
40 | 65 | ||
41 | pic: pic@14000000 { | 66 | pic: pic@14000000 { |
@@ -92,26 +117,36 @@ | |||
92 | rtc: rtc@15000000 { | 117 | rtc: rtc@15000000 { |
93 | compatible = "arm,pl030", "arm,primecell"; | 118 | compatible = "arm,pl030", "arm,primecell"; |
94 | arm,primecell-periphid = <0x00041030>; | 119 | arm,primecell-periphid = <0x00041030>; |
120 | clocks = <&pclk>; | ||
121 | clock-names = "apb_pclk"; | ||
95 | }; | 122 | }; |
96 | 123 | ||
97 | uart0: uart@16000000 { | 124 | uart0: uart@16000000 { |
98 | compatible = "arm,pl010", "arm,primecell"; | 125 | compatible = "arm,pl010", "arm,primecell"; |
99 | arm,primecell-periphid = <0x00041010>; | 126 | arm,primecell-periphid = <0x00041010>; |
127 | clocks = <&uartclk>, <&pclk>; | ||
128 | clock-names = "uartclk", "apb_pclk"; | ||
100 | }; | 129 | }; |
101 | 130 | ||
102 | uart1: uart@17000000 { | 131 | uart1: uart@17000000 { |
103 | compatible = "arm,pl010", "arm,primecell"; | 132 | compatible = "arm,pl010", "arm,primecell"; |
104 | arm,primecell-periphid = <0x00041010>; | 133 | arm,primecell-periphid = <0x00041010>; |
134 | clocks = <&uartclk>, <&pclk>; | ||
135 | clock-names = "uartclk", "apb_pclk"; | ||
105 | }; | 136 | }; |
106 | 137 | ||
107 | kmi0: kmi@18000000 { | 138 | kmi0: kmi@18000000 { |
108 | compatible = "arm,pl050", "arm,primecell"; | 139 | compatible = "arm,pl050", "arm,primecell"; |
109 | arm,primecell-periphid = <0x00041050>; | 140 | arm,primecell-periphid = <0x00041050>; |
141 | clocks = <&xtal24mhz>, <&pclk>; | ||
142 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
110 | }; | 143 | }; |
111 | 144 | ||
112 | kmi1: kmi@19000000 { | 145 | kmi1: kmi@19000000 { |
113 | compatible = "arm,pl050", "arm,primecell"; | 146 | compatible = "arm,pl050", "arm,primecell"; |
114 | arm,primecell-periphid = <0x00041050>; | 147 | arm,primecell-periphid = <0x00041050>; |
148 | clocks = <&xtal24mhz>, <&pclk>; | ||
149 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
115 | }; | 150 | }; |
116 | }; | 151 | }; |
117 | }; | 152 | }; |
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts index a21c17de9a5e..d43f15b4f79a 100644 --- a/arch/arm/boot/dts/integratorcp.dts +++ b/arch/arm/boot/dts/integratorcp.dts | |||
@@ -13,25 +13,107 @@ | |||
13 | bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; | 13 | bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; |
14 | }; | 14 | }; |
15 | 15 | ||
16 | /* | ||
17 | * The Integrator/CP overall clocking architecture can be found in | ||
18 | * ARM DUI 0184B page 7-28 "Integrator/CP922T system clocks" which | ||
19 | * appear to illustrate the layout used in most configurations. | ||
20 | */ | ||
21 | |||
22 | /* The codec chrystal operates at 24.576 MHz */ | ||
23 | xtal_codec: xtal24.576@24.576M { | ||
24 | #clock-cells = <0>; | ||
25 | compatible = "fixed-clock"; | ||
26 | clock-frequency = <24576000>; | ||
27 | }; | ||
28 | |||
29 | /* The chrystal is divided by 2 by the codec for the AACI bit clock */ | ||
30 | aaci_bitclk: aaci_bitclk@12.288M { | ||
31 | #clock-cells = <0>; | ||
32 | compatible = "fixed-factor-clock"; | ||
33 | clock-div = <2>; | ||
34 | clock-mult = <1>; | ||
35 | clocks = <&xtal_codec>; | ||
36 | }; | ||
37 | |||
38 | /* This is a 25MHz chrystal on the base board */ | ||
39 | xtal25mhz: xtal25mhz@25M { | ||
40 | #clock-cells = <0>; | ||
41 | compatible = "fixed-clock"; | ||
42 | clock-frequency = <25000000>; | ||
43 | }; | ||
44 | |||
45 | /* The UART clock is 14.74 MHz divided from 25MHz by an ICS525 */ | ||
46 | uartclk: uartclk@14.74M { | ||
47 | #clock-cells = <0>; | ||
48 | compatible = "fixed-clock"; | ||
49 | clock-frequency = <14745600>; | ||
50 | }; | ||
51 | |||
52 | /* Actually sysclk I think */ | ||
53 | pclk: pclk@0 { | ||
54 | #clock-cells = <0>; | ||
55 | compatible = "fixed-clock"; | ||
56 | clock-frequency = <0>; | ||
57 | }; | ||
58 | |||
59 | core-module@10000000 { | ||
60 | /* 24 MHz chrystal on the core module */ | ||
61 | xtal24mhz: xtal24mhz@24M { | ||
62 | #clock-cells = <0>; | ||
63 | compatible = "fixed-clock"; | ||
64 | clock-frequency = <24000000>; | ||
65 | }; | ||
66 | |||
67 | /* | ||
68 | * External oscillator on the core module, usually used | ||
69 | * to drive video circuitry. Driven from the 24MHz clock. | ||
70 | */ | ||
71 | auxosc: cm_aux_osc@25M { | ||
72 | #clock-cells = <0>; | ||
73 | compatible = "arm,integrator-cm-auxosc"; | ||
74 | clocks = <&xtal24mhz>; | ||
75 | }; | ||
76 | |||
77 | /* The KMI clock is the 24 MHz oscillator divided to 8MHz */ | ||
78 | kmiclk: kmiclk@1M { | ||
79 | #clock-cells = <0>; | ||
80 | compatible = "fixed-factor-clock"; | ||
81 | clock-div = <3>; | ||
82 | clock-mult = <1>; | ||
83 | clocks = <&xtal24mhz>; | ||
84 | }; | ||
85 | |||
86 | /* The timer clock is the 24 MHz oscillator divided to 1MHz */ | ||
87 | timclk: timclk@1M { | ||
88 | #clock-cells = <0>; | ||
89 | compatible = "fixed-factor-clock"; | ||
90 | clock-div = <24>; | ||
91 | clock-mult = <1>; | ||
92 | clocks = <&xtal24mhz>; | ||
93 | }; | ||
94 | }; | ||
95 | |||
16 | syscon { | 96 | syscon { |
17 | compatible = "arm,integrator-cp-syscon"; | 97 | compatible = "arm,integrator-cp-syscon"; |
18 | reg = <0xcb000000 0x100>; | 98 | reg = <0xcb000000 0x100>; |
19 | }; | 99 | }; |
20 | 100 | ||
21 | timer0: timer@13000000 { | 101 | timer0: timer@13000000 { |
22 | /* TIMER0 runs @ 25MHz */ | 102 | /* TIMER0 runs directly on the 25MHz chrystal */ |
23 | compatible = "arm,integrator-cp-timer"; | 103 | compatible = "arm,integrator-cp-timer"; |
24 | status = "disabled"; | 104 | clocks = <&xtal25mhz>; |
25 | }; | 105 | }; |
26 | 106 | ||
27 | timer1: timer@13000100 { | 107 | timer1: timer@13000100 { |
28 | /* TIMER1 runs @ 1MHz */ | 108 | /* TIMER1 runs @ 1MHz */ |
29 | compatible = "arm,integrator-cp-timer"; | 109 | compatible = "arm,integrator-cp-timer"; |
110 | clocks = <&timclk>; | ||
30 | }; | 111 | }; |
31 | 112 | ||
32 | timer2: timer@13000200 { | 113 | timer2: timer@13000200 { |
33 | /* TIMER2 runs @ 1MHz */ | 114 | /* TIMER2 runs @ 1MHz */ |
34 | compatible = "arm,integrator-cp-timer"; | 115 | compatible = "arm,integrator-cp-timer"; |
116 | clocks = <&timclk>; | ||
35 | }; | 117 | }; |
36 | 118 | ||
37 | pic: pic@14000000 { | 119 | pic: pic@14000000 { |
@@ -74,22 +156,32 @@ | |||
74 | */ | 156 | */ |
75 | rtc@15000000 { | 157 | rtc@15000000 { |
76 | compatible = "arm,pl031", "arm,primecell"; | 158 | compatible = "arm,pl031", "arm,primecell"; |
159 | clocks = <&pclk>; | ||
160 | clock-names = "apb_pclk"; | ||
77 | }; | 161 | }; |
78 | 162 | ||
79 | uart@16000000 { | 163 | uart@16000000 { |
80 | compatible = "arm,pl011", "arm,primecell"; | 164 | compatible = "arm,pl011", "arm,primecell"; |
165 | clocks = <&uartclk>, <&pclk>; | ||
166 | clock-names = "uartclk", "apb_pclk"; | ||
81 | }; | 167 | }; |
82 | 168 | ||
83 | uart@17000000 { | 169 | uart@17000000 { |
84 | compatible = "arm,pl011", "arm,primecell"; | 170 | compatible = "arm,pl011", "arm,primecell"; |
171 | clocks = <&uartclk>, <&pclk>; | ||
172 | clock-names = "uartclk", "apb_pclk"; | ||
85 | }; | 173 | }; |
86 | 174 | ||
87 | kmi@18000000 { | 175 | kmi@18000000 { |
88 | compatible = "arm,pl050", "arm,primecell"; | 176 | compatible = "arm,pl050", "arm,primecell"; |
177 | clocks = <&kmiclk>, <&pclk>; | ||
178 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
89 | }; | 179 | }; |
90 | 180 | ||
91 | kmi@19000000 { | 181 | kmi@19000000 { |
92 | compatible = "arm,pl050", "arm,primecell"; | 182 | compatible = "arm,pl050", "arm,primecell"; |
183 | clocks = <&kmiclk>, <&pclk>; | ||
184 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
93 | }; | 185 | }; |
94 | 186 | ||
95 | /* | 187 | /* |
@@ -100,18 +192,24 @@ | |||
100 | reg = <0x1c000000 0x1000>; | 192 | reg = <0x1c000000 0x1000>; |
101 | interrupts = <23 24>; | 193 | interrupts = <23 24>; |
102 | max-frequency = <515633>; | 194 | max-frequency = <515633>; |
195 | clocks = <&uartclk>, <&pclk>; | ||
196 | clock-names = "mclk", "apb_pclk"; | ||
103 | }; | 197 | }; |
104 | 198 | ||
105 | aaci@1d000000 { | 199 | aaci@1d000000 { |
106 | compatible = "arm,pl041", "arm,primecell"; | 200 | compatible = "arm,pl041", "arm,primecell"; |
107 | reg = <0x1d000000 0x1000>; | 201 | reg = <0x1d000000 0x1000>; |
108 | interrupts = <25>; | 202 | interrupts = <25>; |
203 | clocks = <&pclk>; | ||
204 | clock-names = "apb_pclk"; | ||
109 | }; | 205 | }; |
110 | 206 | ||
111 | clcd@c0000000 { | 207 | clcd@c0000000 { |
112 | compatible = "arm,pl110", "arm,primecell"; | 208 | compatible = "arm,pl110", "arm,primecell"; |
113 | reg = <0xC0000000 0x1000>; | 209 | reg = <0xC0000000 0x1000>; |
114 | interrupts = <22>; | 210 | interrupts = <22>; |
211 | clocks = <&auxosc>, <&pclk>; | ||
212 | clock-names = "clcd", "apb_pclk"; | ||
115 | }; | 213 | }; |
116 | }; | 214 | }; |
117 | }; | 215 | }; |
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index e22520dff8c6..618e5b537eaf 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi | |||
@@ -421,6 +421,29 @@ | |||
421 | clock-output-names = "extal"; | 421 | clock-output-names = "extal"; |
422 | }; | 422 | }; |
423 | 423 | ||
424 | /* | ||
425 | * The external audio clocks are configured as 0 Hz fixed frequency clocks by | ||
426 | * default. Boards that provide audio clocks should override them. | ||
427 | */ | ||
428 | audio_clk_a: audio_clk_a { | ||
429 | compatible = "fixed-clock"; | ||
430 | #clock-cells = <0>; | ||
431 | clock-frequency = <0>; | ||
432 | clock-output-names = "audio_clk_a"; | ||
433 | }; | ||
434 | audio_clk_b: audio_clk_b { | ||
435 | compatible = "fixed-clock"; | ||
436 | #clock-cells = <0>; | ||
437 | clock-frequency = <0>; | ||
438 | clock-output-names = "audio_clk_b"; | ||
439 | }; | ||
440 | audio_clk_c: audio_clk_c { | ||
441 | compatible = "fixed-clock"; | ||
442 | #clock-cells = <0>; | ||
443 | clock-frequency = <0>; | ||
444 | clock-output-names = "audio_clk_c"; | ||
445 | }; | ||
446 | |||
424 | /* Special CPG clocks */ | 447 | /* Special CPG clocks */ |
425 | cpg_clocks: cpg_clocks@e6150000 { | 448 | cpg_clocks: cpg_clocks@e6150000 { |
426 | compatible = "renesas,r8a7790-cpg-clocks", | 449 | compatible = "renesas,r8a7790-cpg-clocks", |
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index ba51d69abbea..4568c9869d44 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi | |||
@@ -92,7 +92,12 @@ | |||
92 | #address-cells = <1>; | 92 | #address-cells = <1>; |
93 | #size-cells = <0>; | 93 | #size-cells = <0>; |
94 | 94 | ||
95 | osc: osc1 { | 95 | osc1: osc1 { |
96 | #clock-cells = <0>; | ||
97 | compatible = "fixed-clock"; | ||
98 | }; | ||
99 | |||
100 | osc2: osc2 { | ||
96 | #clock-cells = <0>; | 101 | #clock-cells = <0>; |
97 | compatible = "fixed-clock"; | 102 | compatible = "fixed-clock"; |
98 | }; | 103 | }; |
@@ -100,7 +105,11 @@ | |||
100 | f2s_periph_ref_clk: f2s_periph_ref_clk { | 105 | f2s_periph_ref_clk: f2s_periph_ref_clk { |
101 | #clock-cells = <0>; | 106 | #clock-cells = <0>; |
102 | compatible = "fixed-clock"; | 107 | compatible = "fixed-clock"; |
103 | clock-frequency = <10000000>; | 108 | }; |
109 | |||
110 | f2s_sdram_ref_clk: f2s_sdram_ref_clk { | ||
111 | #clock-cells = <0>; | ||
112 | compatible = "fixed-clock"; | ||
104 | }; | 113 | }; |
105 | 114 | ||
106 | main_pll: main_pll { | 115 | main_pll: main_pll { |
@@ -108,7 +117,7 @@ | |||
108 | #size-cells = <0>; | 117 | #size-cells = <0>; |
109 | #clock-cells = <0>; | 118 | #clock-cells = <0>; |
110 | compatible = "altr,socfpga-pll-clock"; | 119 | compatible = "altr,socfpga-pll-clock"; |
111 | clocks = <&osc>; | 120 | clocks = <&osc1>; |
112 | reg = <0x40>; | 121 | reg = <0x40>; |
113 | 122 | ||
114 | mpuclk: mpuclk { | 123 | mpuclk: mpuclk { |
@@ -162,7 +171,7 @@ | |||
162 | #size-cells = <0>; | 171 | #size-cells = <0>; |
163 | #clock-cells = <0>; | 172 | #clock-cells = <0>; |
164 | compatible = "altr,socfpga-pll-clock"; | 173 | compatible = "altr,socfpga-pll-clock"; |
165 | clocks = <&osc>; | 174 | clocks = <&osc1>, <&osc2>, <&f2s_periph_ref_clk>; |
166 | reg = <0x80>; | 175 | reg = <0x80>; |
167 | 176 | ||
168 | emac0_clk: emac0_clk { | 177 | emac0_clk: emac0_clk { |
@@ -213,7 +222,7 @@ | |||
213 | #size-cells = <0>; | 222 | #size-cells = <0>; |
214 | #clock-cells = <0>; | 223 | #clock-cells = <0>; |
215 | compatible = "altr,socfpga-pll-clock"; | 224 | compatible = "altr,socfpga-pll-clock"; |
216 | clocks = <&osc>; | 225 | clocks = <&osc1>, <&osc2>, <&f2s_sdram_ref_clk>; |
217 | reg = <0xC0>; | 226 | reg = <0xC0>; |
218 | 227 | ||
219 | ddr_dqs_clk: ddr_dqs_clk { | 228 | ddr_dqs_clk: ddr_dqs_clk { |
@@ -475,6 +484,17 @@ | |||
475 | arm,data-latency = <2 1 1>; | 484 | arm,data-latency = <2 1 1>; |
476 | }; | 485 | }; |
477 | 486 | ||
487 | mmc: dwmmc0@ff704000 { | ||
488 | compatible = "altr,socfpga-dw-mshc"; | ||
489 | reg = <0xff704000 0x1000>; | ||
490 | interrupts = <0 139 4>; | ||
491 | fifo-depth = <0x400>; | ||
492 | #address-cells = <1>; | ||
493 | #size-cells = <0>; | ||
494 | clocks = <&l4_mp_clk>, <&sdmmc_clk>; | ||
495 | clock-names = "biu", "ciu"; | ||
496 | }; | ||
497 | |||
478 | /* Local timer */ | 498 | /* Local timer */ |
479 | timer@fffec600 { | 499 | timer@fffec600 { |
480 | compatible = "arm,cortex-a9-twd-timer"; | 500 | compatible = "arm,cortex-a9-twd-timer"; |
@@ -528,9 +548,9 @@ | |||
528 | reg = <0xffd05000 0x1000>; | 548 | reg = <0xffd05000 0x1000>; |
529 | }; | 549 | }; |
530 | 550 | ||
531 | sysmgr@ffd08000 { | 551 | sysmgr: sysmgr@ffd08000 { |
532 | compatible = "altr,sys-mgr"; | 552 | compatible = "altr,sys-mgr", "syscon"; |
533 | reg = <0xffd08000 0x4000>; | 553 | reg = <0xffd08000 0x4000>; |
534 | }; | 554 | }; |
535 | }; | 555 | }; |
536 | }; | 556 | }; |
diff --git a/arch/arm/boot/dts/socfpga_arria5.dtsi b/arch/arm/boot/dts/socfpga_arria5.dtsi index a85b4043f888..6c87b7070ca7 100644 --- a/arch/arm/boot/dts/socfpga_arria5.dtsi +++ b/arch/arm/boot/dts/socfpga_arria5.dtsi | |||
@@ -27,6 +27,17 @@ | |||
27 | }; | 27 | }; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | dwmmc0@ff704000 { | ||
31 | num-slots = <1>; | ||
32 | supports-highspeed; | ||
33 | broken-cd; | ||
34 | |||
35 | slot@0 { | ||
36 | reg = <0>; | ||
37 | bus-width = <4>; | ||
38 | }; | ||
39 | }; | ||
40 | |||
30 | serial0@ffc02000 { | 41 | serial0@ffc02000 { |
31 | clock-frequency = <100000000>; | 42 | clock-frequency = <100000000>; |
32 | }; | 43 | }; |
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dtsi b/arch/arm/boot/dts/socfpga_cyclone5.dtsi index a8716f6dbe2e..ca41b0ebf461 100644 --- a/arch/arm/boot/dts/socfpga_cyclone5.dtsi +++ b/arch/arm/boot/dts/socfpga_cyclone5.dtsi | |||
@@ -28,6 +28,17 @@ | |||
28 | }; | 28 | }; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | dwmmc0@ff704000 { | ||
32 | num-slots = <1>; | ||
33 | supports-highspeed; | ||
34 | broken-cd; | ||
35 | |||
36 | slot@0 { | ||
37 | reg = <0>; | ||
38 | bus-width = <4>; | ||
39 | }; | ||
40 | }; | ||
41 | |||
31 | ethernet@ff702000 { | 42 | ethernet@ff702000 { |
32 | phy-mode = "rgmii"; | 43 | phy-mode = "rgmii"; |
33 | phy-addr = <0xffffffff>; /* probe for phy addr */ | 44 | phy-addr = <0xffffffff>; /* probe for phy addr */ |
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts index dde2c66c50eb..87d6f759a9c1 100644 --- a/arch/arm/boot/dts/socfpga_vt.dts +++ b/arch/arm/boot/dts/socfpga_vt.dts | |||
@@ -41,6 +41,17 @@ | |||
41 | }; | 41 | }; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | dwmmc0@ff704000 { | ||
45 | num-slots = <1>; | ||
46 | supports-highspeed; | ||
47 | broken-cd; | ||
48 | |||
49 | slot@0 { | ||
50 | reg = <0>; | ||
51 | bus-width = <4>; | ||
52 | }; | ||
53 | }; | ||
54 | |||
44 | ethernet@ff700000 { | 55 | ethernet@ff700000 { |
45 | phy-mode = "gmii"; | 56 | phy-mode = "gmii"; |
46 | status = "okay"; | 57 | status = "okay"; |
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index 53c6a26b633d..fd6bff0c5b96 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c | |||
@@ -271,10 +271,14 @@ static void __init integrator_cp_of_init(struct device_node *np) | |||
271 | void __iomem *base; | 271 | void __iomem *base; |
272 | int irq; | 272 | int irq; |
273 | const char *name = of_get_property(np, "compatible", NULL); | 273 | const char *name = of_get_property(np, "compatible", NULL); |
274 | struct clk *clk; | ||
274 | 275 | ||
275 | base = of_iomap(np, 0); | 276 | base = of_iomap(np, 0); |
276 | if (WARN_ON(!base)) | 277 | if (WARN_ON(!base)) |
277 | return; | 278 | return; |
279 | clk = of_clk_get(np, 0); | ||
280 | if (WARN_ON(IS_ERR(clk))) | ||
281 | return; | ||
278 | 282 | ||
279 | /* Ensure timer is disabled */ | 283 | /* Ensure timer is disabled */ |
280 | writel(0, base + TIMER_CTRL); | 284 | writel(0, base + TIMER_CTRL); |
@@ -283,13 +287,13 @@ static void __init integrator_cp_of_init(struct device_node *np) | |||
283 | goto err; | 287 | goto err; |
284 | 288 | ||
285 | if (!init_count) | 289 | if (!init_count) |
286 | sp804_clocksource_init(base, name); | 290 | __sp804_clocksource_and_sched_clock_init(base, name, clk, 0); |
287 | else { | 291 | else { |
288 | irq = irq_of_parse_and_map(np, 0); | 292 | irq = irq_of_parse_and_map(np, 0); |
289 | if (irq <= 0) | 293 | if (irq <= 0) |
290 | goto err; | 294 | goto err; |
291 | 295 | ||
292 | sp804_clockevents_init(base, irq, name); | 296 | __sp804_clockevents_init(base, irq, clk, name); |
293 | } | 297 | } |
294 | 298 | ||
295 | init_count++; | 299 | init_count++; |
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig index 4e1ce211d43f..e3a05e8801d8 100644 --- a/arch/arm/configs/socfpga_defconfig +++ b/arch/arm/configs/socfpga_defconfig | |||
@@ -52,6 +52,7 @@ CONFIG_BLK_DEV_SD=y | |||
52 | # CONFIG_SCSI_LOWLEVEL is not set | 52 | # CONFIG_SCSI_LOWLEVEL is not set |
53 | CONFIG_NETDEVICES=y | 53 | CONFIG_NETDEVICES=y |
54 | CONFIG_STMMAC_ETH=y | 54 | CONFIG_STMMAC_ETH=y |
55 | CONFIG_MICREL_PHY=y | ||
55 | # CONFIG_STMMAC_PHY_ID_ZERO_WORKAROUND is not set | 56 | # CONFIG_STMMAC_PHY_ID_ZERO_WORKAROUND is not set |
56 | CONFIG_INPUT_EVDEV=y | 57 | CONFIG_INPUT_EVDEV=y |
57 | # CONFIG_SERIO_SERPORT is not set | 58 | # CONFIG_SERIO_SERPORT is not set |
@@ -66,6 +67,9 @@ CONFIG_SERIAL_8250_DW=y | |||
66 | CONFIG_EXT2_FS=y | 67 | CONFIG_EXT2_FS=y |
67 | CONFIG_EXT2_FS_XATTR=y | 68 | CONFIG_EXT2_FS_XATTR=y |
68 | CONFIG_EXT2_FS_POSIX_ACL=y | 69 | CONFIG_EXT2_FS_POSIX_ACL=y |
70 | CONFIG_EXT3_FS=y | ||
71 | CONFIG_NFS_FS=y | ||
72 | CONFIG_ROOT_NFS=y | ||
69 | # CONFIG_DNOTIFY is not set | 73 | # CONFIG_DNOTIFY is not set |
70 | # CONFIG_INOTIFY_USER is not set | 74 | # CONFIG_INOTIFY_USER is not set |
71 | CONFIG_VFAT_FS=y | 75 | CONFIG_VFAT_FS=y |
@@ -82,3 +86,5 @@ CONFIG_DEBUG_INFO=y | |||
82 | CONFIG_ENABLE_DEFAULT_TRACERS=y | 86 | CONFIG_ENABLE_DEFAULT_TRACERS=y |
83 | CONFIG_DEBUG_USER=y | 87 | CONFIG_DEBUG_USER=y |
84 | CONFIG_XZ_DEC=y | 88 | CONFIG_XZ_DEC=y |
89 | CONFIG_MMC=y | ||
90 | CONFIG_MMC_DW=y | ||
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c index f091a9010c2f..ff8b7e76b6e9 100644 --- a/arch/arm/mach-davinci/aemif.c +++ b/arch/arm/mach-davinci/aemif.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | 17 | ||
18 | #include <linux/platform_data/mtd-davinci-aemif.h> | 18 | #include <linux/platform_data/mtd-davinci-aemif.h> |
19 | #include <linux/platform_data/mtd-davinci.h> | ||
19 | 20 | ||
20 | /* Timing value configuration */ | 21 | /* Timing value configuration */ |
21 | 22 | ||
@@ -43,6 +44,17 @@ | |||
43 | WSTROBE(WSTROBE_MAX) | \ | 44 | WSTROBE(WSTROBE_MAX) | \ |
44 | WSETUP(WSETUP_MAX)) | 45 | WSETUP(WSETUP_MAX)) |
45 | 46 | ||
47 | static inline unsigned int davinci_aemif_readl(void __iomem *base, int offset) | ||
48 | { | ||
49 | return readl_relaxed(base + offset); | ||
50 | } | ||
51 | |||
52 | static inline void davinci_aemif_writel(void __iomem *base, | ||
53 | int offset, unsigned long value) | ||
54 | { | ||
55 | writel_relaxed(value, base + offset); | ||
56 | } | ||
57 | |||
46 | /* | 58 | /* |
47 | * aemif_calc_rate - calculate timing data. | 59 | * aemif_calc_rate - calculate timing data. |
48 | * @wanted: The cycle time needed in nanoseconds. | 60 | * @wanted: The cycle time needed in nanoseconds. |
@@ -76,6 +88,7 @@ static int aemif_calc_rate(int wanted, unsigned long clk, int max) | |||
76 | * @t: timing values to be progammed | 88 | * @t: timing values to be progammed |
77 | * @base: The virtual base address of the AEMIF interface | 89 | * @base: The virtual base address of the AEMIF interface |
78 | * @cs: chip-select to program the timing values for | 90 | * @cs: chip-select to program the timing values for |
91 | * @clkrate: the AEMIF clkrate | ||
79 | * | 92 | * |
80 | * This function programs the given timing values (in real clock) into the | 93 | * This function programs the given timing values (in real clock) into the |
81 | * AEMIF registers taking the AEMIF clock into account. | 94 | * AEMIF registers taking the AEMIF clock into account. |
@@ -86,24 +99,17 @@ static int aemif_calc_rate(int wanted, unsigned long clk, int max) | |||
86 | * | 99 | * |
87 | * Returns 0 on success, else negative errno. | 100 | * Returns 0 on success, else negative errno. |
88 | */ | 101 | */ |
89 | int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, | 102 | static int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, |
90 | void __iomem *base, unsigned cs) | 103 | void __iomem *base, unsigned cs, |
104 | unsigned long clkrate) | ||
91 | { | 105 | { |
92 | unsigned set, val; | 106 | unsigned set, val; |
93 | int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; | 107 | int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; |
94 | unsigned offset = A1CR_OFFSET + cs * 4; | 108 | unsigned offset = A1CR_OFFSET + cs * 4; |
95 | struct clk *aemif_clk; | ||
96 | unsigned long clkrate; | ||
97 | 109 | ||
98 | if (!t) | 110 | if (!t) |
99 | return 0; /* Nothing to do */ | 111 | return 0; /* Nothing to do */ |
100 | 112 | ||
101 | aemif_clk = clk_get(NULL, "aemif"); | ||
102 | if (IS_ERR(aemif_clk)) | ||
103 | return PTR_ERR(aemif_clk); | ||
104 | |||
105 | clkrate = clk_get_rate(aemif_clk); | ||
106 | |||
107 | clkrate /= 1000; /* turn clock into kHz for ease of use */ | 113 | clkrate /= 1000; /* turn clock into kHz for ease of use */ |
108 | 114 | ||
109 | ta = aemif_calc_rate(t->ta, clkrate, TA_MAX); | 115 | ta = aemif_calc_rate(t->ta, clkrate, TA_MAX); |
@@ -130,4 +136,83 @@ int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, | |||
130 | 136 | ||
131 | return 0; | 137 | return 0; |
132 | } | 138 | } |
133 | EXPORT_SYMBOL(davinci_aemif_setup_timing); | 139 | |
140 | /** | ||
141 | * davinci_aemif_setup - setup AEMIF interface by davinci_nand_pdata | ||
142 | * @pdev - link to platform device to setup settings for | ||
143 | * | ||
144 | * This function does not use any locking while programming the AEMIF | ||
145 | * because it is expected that there is only one user of a given | ||
146 | * chip-select. | ||
147 | * | ||
148 | * Returns 0 on success, else negative errno. | ||
149 | */ | ||
150 | int davinci_aemif_setup(struct platform_device *pdev) | ||
151 | { | ||
152 | struct davinci_nand_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
153 | uint32_t val; | ||
154 | unsigned long clkrate; | ||
155 | struct resource *res; | ||
156 | void __iomem *base; | ||
157 | struct clk *clk; | ||
158 | int ret = 0; | ||
159 | |||
160 | clk = clk_get(&pdev->dev, "aemif"); | ||
161 | if (IS_ERR(clk)) { | ||
162 | ret = PTR_ERR(clk); | ||
163 | dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret); | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | ret = clk_prepare_enable(clk); | ||
168 | if (ret < 0) { | ||
169 | dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n", | ||
170 | ret); | ||
171 | goto err_put; | ||
172 | } | ||
173 | |||
174 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
175 | if (!res) { | ||
176 | dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n"); | ||
177 | ret = -ENOMEM; | ||
178 | goto err; | ||
179 | } | ||
180 | |||
181 | base = ioremap(res->start, resource_size(res)); | ||
182 | if (!base) { | ||
183 | dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res); | ||
184 | ret = -ENOMEM; | ||
185 | goto err; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Setup Async configuration register in case we did not boot | ||
190 | * from NAND and so bootloader did not bother to set it up. | ||
191 | */ | ||
192 | val = davinci_aemif_readl(base, A1CR_OFFSET + pdev->id * 4); | ||
193 | /* | ||
194 | * Extended Wait is not valid and Select Strobe mode is not | ||
195 | * used | ||
196 | */ | ||
197 | val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK); | ||
198 | if (pdata->options & NAND_BUSWIDTH_16) | ||
199 | val |= 0x1; | ||
200 | |||
201 | davinci_aemif_writel(base, A1CR_OFFSET + pdev->id * 4, val); | ||
202 | |||
203 | clkrate = clk_get_rate(clk); | ||
204 | |||
205 | if (pdata->timing) | ||
206 | ret = davinci_aemif_setup_timing(pdata->timing, base, pdev->id, | ||
207 | clkrate); | ||
208 | |||
209 | if (ret < 0) | ||
210 | dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); | ||
211 | |||
212 | iounmap(base); | ||
213 | err: | ||
214 | clk_disable_unprepare(clk); | ||
215 | err_put: | ||
216 | clk_put(clk); | ||
217 | return ret; | ||
218 | } | ||
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index d1f45af7a530..5623131c4f0b 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c | |||
@@ -419,6 +419,9 @@ static inline void da830_evm_init_nand(int mux_mode) | |||
419 | if (ret) | 419 | if (ret) |
420 | pr_warning("da830_evm_init: NAND device not registered.\n"); | 420 | pr_warning("da830_evm_init: NAND device not registered.\n"); |
421 | 421 | ||
422 | if (davinci_aemif_setup(&da830_evm_nand_device)) | ||
423 | pr_warn("%s: Cannot configure AEMIF.\n", __func__); | ||
424 | |||
422 | gpio_direction_output(mux_mode, 1); | 425 | gpio_direction_output(mux_mode, 1); |
423 | } | 426 | } |
424 | #else | 427 | #else |
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index e0af0eccde8f..234c5bb091f5 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
@@ -358,6 +358,9 @@ static inline void da850_evm_setup_nor_nand(void) | |||
358 | 358 | ||
359 | platform_add_devices(da850_evm_devices, | 359 | platform_add_devices(da850_evm_devices, |
360 | ARRAY_SIZE(da850_evm_devices)); | 360 | ARRAY_SIZE(da850_evm_devices)); |
361 | |||
362 | if (davinci_aemif_setup(&da850_evm_nandflash_device)) | ||
363 | pr_warn("%s: Cannot configure AEMIF.\n", __func__); | ||
361 | } | 364 | } |
362 | } | 365 | } |
363 | 366 | ||
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 3de4dc9a1698..e583e58b5e1e 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c | |||
@@ -778,6 +778,11 @@ static __init void davinci_evm_init(void) | |||
778 | /* only one device will be jumpered and detected */ | 778 | /* only one device will be jumpered and detected */ |
779 | if (HAS_NAND) { | 779 | if (HAS_NAND) { |
780 | platform_device_register(&davinci_evm_nandflash_device); | 780 | platform_device_register(&davinci_evm_nandflash_device); |
781 | |||
782 | if (davinci_aemif_setup(&davinci_evm_nandflash_device)) | ||
783 | pr_warn("%s: Cannot configure AEMIF.\n", | ||
784 | __func__); | ||
785 | |||
781 | evm_leds[7].default_trigger = "nand-disk"; | 786 | evm_leds[7].default_trigger = "nand-disk"; |
782 | if (HAS_NOR) | 787 | if (HAS_NOR) |
783 | pr_warning("WARNING: both NAND and NOR flash " | 788 | pr_warning("WARNING: both NAND and NOR flash " |
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 13d0801fd6b1..ae129bc49273 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c | |||
@@ -805,6 +805,9 @@ static __init void evm_init(void) | |||
805 | 805 | ||
806 | platform_device_register(&davinci_nand_device); | 806 | platform_device_register(&davinci_nand_device); |
807 | 807 | ||
808 | if (davinci_aemif_setup(&davinci_nand_device)) | ||
809 | pr_warn("%s: Cannot configure AEMIF.\n", __func__); | ||
810 | |||
808 | dm646x_init_edma(dm646x_edma_rsv); | 811 | dm646x_init_edma(dm646x_edma_rsv); |
809 | 812 | ||
810 | if (HAS_ATA) | 813 | if (HAS_ATA) |
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 7aa105b1fd0f..96fc00a167f5 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <mach/cp_intc.h> | 27 | #include <mach/cp_intc.h> |
28 | #include <mach/da8xx.h> | 28 | #include <mach/da8xx.h> |
29 | #include <linux/platform_data/mtd-davinci.h> | 29 | #include <linux/platform_data/mtd-davinci.h> |
30 | #include <linux/platform_data/mtd-davinci-aemif.h> | ||
30 | #include <mach/mux.h> | 31 | #include <mach/mux.h> |
31 | #include <linux/platform_data/spi-davinci.h> | 32 | #include <linux/platform_data/spi-davinci.h> |
32 | 33 | ||
@@ -432,6 +433,9 @@ static void __init mityomapl138_setup_nand(void) | |||
432 | { | 433 | { |
433 | platform_add_devices(mityomapl138_devices, | 434 | platform_add_devices(mityomapl138_devices, |
434 | ARRAY_SIZE(mityomapl138_devices)); | 435 | ARRAY_SIZE(mityomapl138_devices)); |
436 | |||
437 | if (davinci_aemif_setup(&mityomapl138_nandflash_device)) | ||
438 | pr_warn("%s: Cannot configure AEMIF.\n", __func__); | ||
435 | } | 439 | } |
436 | 440 | ||
437 | static const short mityomap_mii_pins[] = { | 441 | static const short mityomap_mii_pins[] = { |
diff --git a/arch/arm/mach-dove/include/mach/bridge-regs.h b/arch/arm/mach-dove/include/mach/bridge-regs.h index 5362df3df89f..f4a5b34489b7 100644 --- a/arch/arm/mach-dove/include/mach/bridge-regs.h +++ b/arch/arm/mach-dove/include/mach/bridge-regs.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define CPU_CTRL_PCIE1_LINK 0x00000008 | 21 | #define CPU_CTRL_PCIE1_LINK 0x00000008 |
22 | 22 | ||
23 | #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) | 23 | #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) |
24 | #define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108) | ||
24 | #define SOFT_RESET_OUT_EN 0x00000004 | 25 | #define SOFT_RESET_OUT_EN 0x00000004 |
25 | 26 | ||
26 | #define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c) | 27 | #define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c) |
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index e00025bbbe89..ba18214c9aca 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c | |||
@@ -35,56 +35,6 @@ | |||
35 | #include "common.h" | 35 | #include "common.h" |
36 | #include "regs-pmu.h" | 36 | #include "regs-pmu.h" |
37 | 37 | ||
38 | #define EXYNOS4_EPLL_LOCK (S5P_VA_CMU + 0x0C010) | ||
39 | #define EXYNOS4_VPLL_LOCK (S5P_VA_CMU + 0x0C020) | ||
40 | |||
41 | #define EXYNOS4_EPLL_CON0 (S5P_VA_CMU + 0x0C110) | ||
42 | #define EXYNOS4_EPLL_CON1 (S5P_VA_CMU + 0x0C114) | ||
43 | #define EXYNOS4_VPLL_CON0 (S5P_VA_CMU + 0x0C120) | ||
44 | #define EXYNOS4_VPLL_CON1 (S5P_VA_CMU + 0x0C124) | ||
45 | |||
46 | #define EXYNOS4_CLKSRC_MASK_TOP (S5P_VA_CMU + 0x0C310) | ||
47 | #define EXYNOS4_CLKSRC_MASK_CAM (S5P_VA_CMU + 0x0C320) | ||
48 | #define EXYNOS4_CLKSRC_MASK_TV (S5P_VA_CMU + 0x0C324) | ||
49 | #define EXYNOS4_CLKSRC_MASK_LCD0 (S5P_VA_CMU + 0x0C334) | ||
50 | #define EXYNOS4_CLKSRC_MASK_MAUDIO (S5P_VA_CMU + 0x0C33C) | ||
51 | #define EXYNOS4_CLKSRC_MASK_FSYS (S5P_VA_CMU + 0x0C340) | ||
52 | #define EXYNOS4_CLKSRC_MASK_PERIL0 (S5P_VA_CMU + 0x0C350) | ||
53 | #define EXYNOS4_CLKSRC_MASK_PERIL1 (S5P_VA_CMU + 0x0C354) | ||
54 | |||
55 | #define EXYNOS4_CLKSRC_MASK_DMC (S5P_VA_CMU + 0x10300) | ||
56 | |||
57 | #define EXYNOS4_EPLLCON0_LOCKED_SHIFT (29) | ||
58 | #define EXYNOS4_VPLLCON0_LOCKED_SHIFT (29) | ||
59 | |||
60 | #define EXYNOS4210_CLKSRC_MASK_LCD1 (S5P_VA_CMU + 0x0C338) | ||
61 | |||
62 | static const struct sleep_save exynos4_set_clksrc[] = { | ||
63 | { .reg = EXYNOS4_CLKSRC_MASK_TOP , .val = 0x00000001, }, | ||
64 | { .reg = EXYNOS4_CLKSRC_MASK_CAM , .val = 0x11111111, }, | ||
65 | { .reg = EXYNOS4_CLKSRC_MASK_TV , .val = 0x00000111, }, | ||
66 | { .reg = EXYNOS4_CLKSRC_MASK_LCD0 , .val = 0x00001111, }, | ||
67 | { .reg = EXYNOS4_CLKSRC_MASK_MAUDIO , .val = 0x00000001, }, | ||
68 | { .reg = EXYNOS4_CLKSRC_MASK_FSYS , .val = 0x01011111, }, | ||
69 | { .reg = EXYNOS4_CLKSRC_MASK_PERIL0 , .val = 0x01111111, }, | ||
70 | { .reg = EXYNOS4_CLKSRC_MASK_PERIL1 , .val = 0x01110111, }, | ||
71 | { .reg = EXYNOS4_CLKSRC_MASK_DMC , .val = 0x00010000, }, | ||
72 | }; | ||
73 | |||
74 | static const struct sleep_save exynos4210_set_clksrc[] = { | ||
75 | { .reg = EXYNOS4210_CLKSRC_MASK_LCD1 , .val = 0x00001111, }, | ||
76 | }; | ||
77 | |||
78 | static struct sleep_save exynos4_epll_save[] = { | ||
79 | SAVE_ITEM(EXYNOS4_EPLL_CON0), | ||
80 | SAVE_ITEM(EXYNOS4_EPLL_CON1), | ||
81 | }; | ||
82 | |||
83 | static struct sleep_save exynos4_vpll_save[] = { | ||
84 | SAVE_ITEM(EXYNOS4_VPLL_CON0), | ||
85 | SAVE_ITEM(EXYNOS4_VPLL_CON1), | ||
86 | }; | ||
87 | |||
88 | static struct sleep_save exynos5_sys_save[] = { | 38 | static struct sleep_save exynos5_sys_save[] = { |
89 | SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), | 39 | SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), |
90 | }; | 40 | }; |
@@ -124,10 +74,7 @@ static void exynos_pm_prepare(void) | |||
124 | 74 | ||
125 | s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | 75 | s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); |
126 | 76 | ||
127 | if (!soc_is_exynos5250()) { | 77 | if (soc_is_exynos5250()) { |
128 | s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); | ||
129 | s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); | ||
130 | } else { | ||
131 | s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); | 78 | s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); |
132 | /* Disable USE_RETENTION of JPEG_MEM_OPTION */ | 79 | /* Disable USE_RETENTION of JPEG_MEM_OPTION */ |
133 | tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); | 80 | tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); |
@@ -143,15 +90,6 @@ static void exynos_pm_prepare(void) | |||
143 | /* ensure at least INFORM0 has the resume address */ | 90 | /* ensure at least INFORM0 has the resume address */ |
144 | 91 | ||
145 | __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); | 92 | __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); |
146 | |||
147 | /* Before enter central sequence mode, clock src register have to set */ | ||
148 | |||
149 | if (!soc_is_exynos5250()) | ||
150 | s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); | ||
151 | |||
152 | if (soc_is_exynos4210()) | ||
153 | s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc)); | ||
154 | |||
155 | } | 93 | } |
156 | 94 | ||
157 | static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) | 95 | static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) |
@@ -162,73 +100,6 @@ static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) | |||
162 | return 0; | 100 | return 0; |
163 | } | 101 | } |
164 | 102 | ||
165 | static unsigned long pll_base_rate; | ||
166 | |||
167 | static void exynos4_restore_pll(void) | ||
168 | { | ||
169 | unsigned long pll_con, locktime, lockcnt; | ||
170 | unsigned long pll_in_rate; | ||
171 | unsigned int p_div, epll_wait = 0, vpll_wait = 0; | ||
172 | |||
173 | if (pll_base_rate == 0) | ||
174 | return; | ||
175 | |||
176 | pll_in_rate = pll_base_rate; | ||
177 | |||
178 | /* EPLL */ | ||
179 | pll_con = exynos4_epll_save[0].val; | ||
180 | |||
181 | if (pll_con & (1 << 31)) { | ||
182 | pll_con &= (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT); | ||
183 | p_div = (pll_con >> PLL46XX_PDIV_SHIFT); | ||
184 | |||
185 | pll_in_rate /= 1000000; | ||
186 | |||
187 | locktime = (3000 / pll_in_rate) * p_div; | ||
188 | lockcnt = locktime * 10000 / (10000 / pll_in_rate); | ||
189 | |||
190 | __raw_writel(lockcnt, EXYNOS4_EPLL_LOCK); | ||
191 | |||
192 | s3c_pm_do_restore_core(exynos4_epll_save, | ||
193 | ARRAY_SIZE(exynos4_epll_save)); | ||
194 | epll_wait = 1; | ||
195 | } | ||
196 | |||
197 | pll_in_rate = pll_base_rate; | ||
198 | |||
199 | /* VPLL */ | ||
200 | pll_con = exynos4_vpll_save[0].val; | ||
201 | |||
202 | if (pll_con & (1 << 31)) { | ||
203 | pll_in_rate /= 1000000; | ||
204 | /* 750us */ | ||
205 | locktime = 750; | ||
206 | lockcnt = locktime * 10000 / (10000 / pll_in_rate); | ||
207 | |||
208 | __raw_writel(lockcnt, EXYNOS4_VPLL_LOCK); | ||
209 | |||
210 | s3c_pm_do_restore_core(exynos4_vpll_save, | ||
211 | ARRAY_SIZE(exynos4_vpll_save)); | ||
212 | vpll_wait = 1; | ||
213 | } | ||
214 | |||
215 | /* Wait PLL locking */ | ||
216 | |||
217 | do { | ||
218 | if (epll_wait) { | ||
219 | pll_con = __raw_readl(EXYNOS4_EPLL_CON0); | ||
220 | if (pll_con & (1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT)) | ||
221 | epll_wait = 0; | ||
222 | } | ||
223 | |||
224 | if (vpll_wait) { | ||
225 | pll_con = __raw_readl(EXYNOS4_VPLL_CON0); | ||
226 | if (pll_con & (1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT)) | ||
227 | vpll_wait = 0; | ||
228 | } | ||
229 | } while (epll_wait || vpll_wait); | ||
230 | } | ||
231 | |||
232 | static struct subsys_interface exynos_pm_interface = { | 103 | static struct subsys_interface exynos_pm_interface = { |
233 | .name = "exynos_pm", | 104 | .name = "exynos_pm", |
234 | .subsys = &exynos_subsys, | 105 | .subsys = &exynos_subsys, |
@@ -237,7 +108,6 @@ static struct subsys_interface exynos_pm_interface = { | |||
237 | 108 | ||
238 | static __init int exynos_pm_drvinit(void) | 109 | static __init int exynos_pm_drvinit(void) |
239 | { | 110 | { |
240 | struct clk *pll_base; | ||
241 | unsigned int tmp; | 111 | unsigned int tmp; |
242 | 112 | ||
243 | if (soc_is_exynos5440()) | 113 | if (soc_is_exynos5440()) |
@@ -251,15 +121,6 @@ static __init int exynos_pm_drvinit(void) | |||
251 | tmp |= ((0xFF << 8) | (0x1F << 1)); | 121 | tmp |= ((0xFF << 8) | (0x1F << 1)); |
252 | __raw_writel(tmp, S5P_WAKEUP_MASK); | 122 | __raw_writel(tmp, S5P_WAKEUP_MASK); |
253 | 123 | ||
254 | if (!soc_is_exynos5250()) { | ||
255 | pll_base = clk_get(NULL, "xtal"); | ||
256 | |||
257 | if (!IS_ERR(pll_base)) { | ||
258 | pll_base_rate = clk_get_rate(pll_base); | ||
259 | clk_put(pll_base); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | return subsys_interface_register(&exynos_pm_interface); | 124 | return subsys_interface_register(&exynos_pm_interface); |
264 | } | 125 | } |
265 | arch_initcall(exynos_pm_drvinit); | 126 | arch_initcall(exynos_pm_drvinit); |
@@ -343,13 +204,8 @@ static void exynos_pm_resume(void) | |||
343 | 204 | ||
344 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | 205 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); |
345 | 206 | ||
346 | if (!soc_is_exynos5250()) { | 207 | if (IS_ENABLED(CONFIG_SMP) && !soc_is_exynos5250()) |
347 | exynos4_restore_pll(); | ||
348 | |||
349 | #ifdef CONFIG_SMP | ||
350 | scu_enable(S5P_VA_SCU); | 208 | scu_enable(S5P_VA_SCU); |
351 | #endif | ||
352 | } | ||
353 | 209 | ||
354 | early_wakeup: | 210 | early_wakeup: |
355 | 211 | ||
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index 271a255864d2..ba43321001d8 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig | |||
@@ -30,6 +30,9 @@ config ARCH_CINTEGRATOR | |||
30 | config INTEGRATOR_IMPD1 | 30 | config INTEGRATOR_IMPD1 |
31 | tristate "Include support for Integrator/IM-PD1" | 31 | tristate "Include support for Integrator/IM-PD1" |
32 | depends on ARCH_INTEGRATOR_AP | 32 | depends on ARCH_INTEGRATOR_AP |
33 | select ARCH_REQUIRE_GPIOLIB | ||
34 | select ARM_VIC | ||
35 | select GPIO_PL061 if GPIOLIB | ||
33 | help | 36 | help |
34 | The IM-PD1 is an add-on logic module for the Integrator which | 37 | The IM-PD1 is an add-on logic module for the Integrator which |
35 | allows ARM(R) Ltd PrimeCells to be developed and evaluated. | 38 | allows ARM(R) Ltd PrimeCells to be developed and evaluated. |
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 9f82f9dcbb98..d9b784824808 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/platform_data/clk-integrator.h> | 24 | #include <linux/platform_data/clk-integrator.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/irqchip/arm-vic.h> | ||
26 | 27 | ||
27 | #include <mach/lm.h> | 28 | #include <mach/lm.h> |
28 | #include <mach/impd1.h> | 29 | #include <mach/impd1.h> |
@@ -35,6 +36,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position"); | |||
35 | 36 | ||
36 | struct impd1_module { | 37 | struct impd1_module { |
37 | void __iomem *base; | 38 | void __iomem *base; |
39 | void __iomem *vic_base; | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | void impd1_tweak_control(struct device *dev, u32 mask, u32 val) | 42 | void impd1_tweak_control(struct device *dev, u32 mask, u32 val) |
@@ -262,9 +264,6 @@ struct impd1_device { | |||
262 | 264 | ||
263 | static struct impd1_device impd1_devs[] = { | 265 | static struct impd1_device impd1_devs[] = { |
264 | { | 266 | { |
265 | .offset = 0x03000000, | ||
266 | .id = 0x00041190, | ||
267 | }, { | ||
268 | .offset = 0x00100000, | 267 | .offset = 0x00100000, |
269 | .irq = { 1 }, | 268 | .irq = { 1 }, |
270 | .id = 0x00141011, | 269 | .id = 0x00141011, |
@@ -304,46 +303,72 @@ static struct impd1_device impd1_devs[] = { | |||
304 | } | 303 | } |
305 | }; | 304 | }; |
306 | 305 | ||
307 | static int impd1_probe(struct lm_device *dev) | 306 | /* |
307 | * Valid IRQs: 0 thru 9 and 11, 10 unused. | ||
308 | */ | ||
309 | #define IMPD1_VALID_IRQS 0x00000bffU | ||
310 | |||
311 | static int __init impd1_probe(struct lm_device *dev) | ||
308 | { | 312 | { |
309 | struct impd1_module *impd1; | 313 | struct impd1_module *impd1; |
310 | int i, ret; | 314 | int irq_base; |
315 | int i; | ||
311 | 316 | ||
312 | if (dev->id != module_id) | 317 | if (dev->id != module_id) |
313 | return -EINVAL; | 318 | return -EINVAL; |
314 | 319 | ||
315 | if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers")) | 320 | if (!devm_request_mem_region(&dev->dev, dev->resource.start, |
321 | SZ_4K, "LM registers")) | ||
316 | return -EBUSY; | 322 | return -EBUSY; |
317 | 323 | ||
318 | impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL); | 324 | impd1 = devm_kzalloc(&dev->dev, sizeof(struct impd1_module), |
319 | if (!impd1) { | 325 | GFP_KERNEL); |
320 | ret = -ENOMEM; | 326 | if (!impd1) |
321 | goto release_lm; | 327 | return -ENOMEM; |
322 | } | ||
323 | 328 | ||
324 | impd1->base = ioremap(dev->resource.start, SZ_4K); | 329 | impd1->base = devm_ioremap(&dev->dev, dev->resource.start, SZ_4K); |
325 | if (!impd1->base) { | 330 | if (!impd1->base) |
326 | ret = -ENOMEM; | 331 | return -ENOMEM; |
327 | goto free_impd1; | ||
328 | } | ||
329 | 332 | ||
330 | lm_set_drvdata(dev, impd1); | 333 | integrator_impd1_clk_init(impd1->base, dev->id); |
331 | 334 | ||
332 | printk("IM-PD1 found at 0x%08lx\n", | 335 | if (!devm_request_mem_region(&dev->dev, |
333 | (unsigned long)dev->resource.start); | 336 | dev->resource.start + 0x03000000, |
337 | SZ_4K, "VIC")) | ||
338 | return -EBUSY; | ||
334 | 339 | ||
335 | integrator_impd1_clk_init(impd1->base, dev->id); | 340 | impd1->vic_base = devm_ioremap(&dev->dev, |
341 | dev->resource.start + 0x03000000, | ||
342 | SZ_4K); | ||
343 | if (!impd1->vic_base) | ||
344 | return -ENOMEM; | ||
345 | |||
346 | irq_base = vic_init_cascaded(impd1->vic_base, dev->irq, | ||
347 | IMPD1_VALID_IRQS, 0); | ||
348 | |||
349 | lm_set_drvdata(dev, impd1); | ||
350 | |||
351 | dev_info(&dev->dev, "IM-PD1 found at 0x%08lx\n", | ||
352 | (unsigned long)dev->resource.start); | ||
336 | 353 | ||
337 | for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { | 354 | for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { |
338 | struct impd1_device *idev = impd1_devs + i; | 355 | struct impd1_device *idev = impd1_devs + i; |
339 | struct amba_device *d; | 356 | struct amba_device *d; |
340 | unsigned long pc_base; | 357 | unsigned long pc_base; |
341 | char devname[32]; | 358 | char devname[32]; |
359 | int irq1 = idev->irq[0]; | ||
360 | int irq2 = idev->irq[1]; | ||
361 | |||
362 | /* Translate IRQs to IM-PD1 local numberspace */ | ||
363 | if (irq1) | ||
364 | irq1 += irq_base; | ||
365 | if (irq2) | ||
366 | irq2 += irq_base; | ||
342 | 367 | ||
343 | pc_base = dev->resource.start + idev->offset; | 368 | pc_base = dev->resource.start + idev->offset; |
344 | snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); | 369 | snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); |
345 | d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K, | 370 | d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K, |
346 | dev->irq, dev->irq, | 371 | irq1, irq2, |
347 | idev->platform_data, idev->id, | 372 | idev->platform_data, idev->id, |
348 | &dev->resource); | 373 | &dev->resource); |
349 | if (IS_ERR(d)) { | 374 | if (IS_ERR(d)) { |
@@ -353,14 +378,6 @@ static int impd1_probe(struct lm_device *dev) | |||
353 | } | 378 | } |
354 | 379 | ||
355 | return 0; | 380 | return 0; |
356 | |||
357 | free_impd1: | ||
358 | if (impd1 && impd1->base) | ||
359 | iounmap(impd1->base); | ||
360 | kfree(impd1); | ||
361 | release_lm: | ||
362 | release_mem_region(dev->resource.start, SZ_4K); | ||
363 | return ret; | ||
364 | } | 381 | } |
365 | 382 | ||
366 | static int impd1_remove_one(struct device *dev, void *data) | 383 | static int impd1_remove_one(struct device *dev, void *data) |
@@ -371,16 +388,10 @@ static int impd1_remove_one(struct device *dev, void *data) | |||
371 | 388 | ||
372 | static void impd1_remove(struct lm_device *dev) | 389 | static void impd1_remove(struct lm_device *dev) |
373 | { | 390 | { |
374 | struct impd1_module *impd1 = lm_get_drvdata(dev); | ||
375 | |||
376 | device_for_each_child(&dev->dev, NULL, impd1_remove_one); | 391 | device_for_each_child(&dev->dev, NULL, impd1_remove_one); |
377 | integrator_impd1_clk_exit(dev->id); | 392 | integrator_impd1_clk_exit(dev->id); |
378 | 393 | ||
379 | lm_set_drvdata(dev, NULL); | 394 | lm_set_drvdata(dev, NULL); |
380 | |||
381 | iounmap(impd1->base); | ||
382 | kfree(impd1); | ||
383 | release_mem_region(dev->resource.start, SZ_4K); | ||
384 | } | 395 | } |
385 | 396 | ||
386 | static struct lm_driver impd1_driver = { | 397 | static struct lm_driver impd1_driver = { |
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index e4f27f0e56ac..cc0857cab2e1 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/sys_soc.h> | 42 | #include <linux/sys_soc.h> |
43 | #include <linux/termios.h> | 43 | #include <linux/termios.h> |
44 | #include <linux/sched_clock.h> | 44 | #include <linux/sched_clock.h> |
45 | #include <linux/clk-provider.h> | ||
45 | 46 | ||
46 | #include <mach/hardware.h> | 47 | #include <mach/hardware.h> |
47 | #include <mach/platform.h> | 48 | #include <mach/platform.h> |
@@ -402,10 +403,7 @@ static void __init ap_of_timer_init(void) | |||
402 | struct clk *clk; | 403 | struct clk *clk; |
403 | unsigned long rate; | 404 | unsigned long rate; |
404 | 405 | ||
405 | clk = clk_get_sys("ap_timer", NULL); | 406 | of_clk_init(NULL); |
406 | BUG_ON(IS_ERR(clk)); | ||
407 | clk_prepare_enable(clk); | ||
408 | rate = clk_get_rate(clk); | ||
409 | 407 | ||
410 | err = of_property_read_string(of_aliases, | 408 | err = of_property_read_string(of_aliases, |
411 | "arm,timer-primary", &path); | 409 | "arm,timer-primary", &path); |
@@ -415,6 +413,12 @@ static void __init ap_of_timer_init(void) | |||
415 | base = of_iomap(node, 0); | 413 | base = of_iomap(node, 0); |
416 | if (WARN_ON(!base)) | 414 | if (WARN_ON(!base)) |
417 | return; | 415 | return; |
416 | |||
417 | clk = of_clk_get(node, 0); | ||
418 | BUG_ON(IS_ERR(clk)); | ||
419 | clk_prepare_enable(clk); | ||
420 | rate = clk_get_rate(clk); | ||
421 | |||
418 | writel(0, base + TIMER_CTRL); | 422 | writel(0, base + TIMER_CTRL); |
419 | integrator_clocksource_init(rate, base); | 423 | integrator_clocksource_init(rate, base); |
420 | 424 | ||
@@ -427,6 +431,12 @@ static void __init ap_of_timer_init(void) | |||
427 | if (WARN_ON(!base)) | 431 | if (WARN_ON(!base)) |
428 | return; | 432 | return; |
429 | irq = irq_of_parse_and_map(node, 0); | 433 | irq = irq_of_parse_and_map(node, 0); |
434 | |||
435 | clk = of_clk_get(node, 0); | ||
436 | BUG_ON(IS_ERR(clk)); | ||
437 | clk_prepare_enable(clk); | ||
438 | rate = clk_get_rate(clk); | ||
439 | |||
430 | writel(0, base + TIMER_CTRL); | 440 | writel(0, base + TIMER_CTRL); |
431 | integrator_clockevent_init(rate, base, irq); | 441 | integrator_clockevent_init(rate, base, irq); |
432 | } | 442 | } |
@@ -440,7 +450,6 @@ static void __init ap_init_irq_of(void) | |||
440 | { | 450 | { |
441 | cm_init(); | 451 | cm_init(); |
442 | of_irq_init(fpga_irq_of_match); | 452 | of_irq_init(fpga_irq_of_match); |
443 | integrator_clk_init(false); | ||
444 | } | 453 | } |
445 | 454 | ||
446 | /* For the Device Tree, add in the UART callbacks as AUXDATA */ | 455 | /* For the Device Tree, add in the UART callbacks as AUXDATA */ |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a3ef961e4a93..0ad5f60598c8 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/irqchip/versatile-fpga.h> | 23 | #include <linux/irqchip/versatile-fpga.h> |
24 | #include <linux/gfp.h> | 24 | #include <linux/gfp.h> |
25 | #include <linux/mtd/physmap.h> | 25 | #include <linux/mtd/physmap.h> |
26 | #include <linux/platform_data/clk-integrator.h> | ||
27 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
28 | #include <linux/of_address.h> | 27 | #include <linux/of_address.h> |
29 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
@@ -33,8 +32,6 @@ | |||
33 | #include <mach/platform.h> | 32 | #include <mach/platform.h> |
34 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
35 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
36 | #include <asm/hardware/arm_timer.h> | ||
37 | #include <asm/hardware/icst.h> | ||
38 | 35 | ||
39 | #include <mach/lm.h> | 36 | #include <mach/lm.h> |
40 | 37 | ||
@@ -43,8 +40,6 @@ | |||
43 | #include <asm/mach/map.h> | 40 | #include <asm/mach/map.h> |
44 | #include <asm/mach/time.h> | 41 | #include <asm/mach/time.h> |
45 | 42 | ||
46 | #include <asm/hardware/timer-sp.h> | ||
47 | |||
48 | #include <plat/clcd.h> | 43 | #include <plat/clcd.h> |
49 | #include <plat/sched_clock.h> | 44 | #include <plat/sched_clock.h> |
50 | 45 | ||
@@ -250,7 +245,6 @@ static void __init intcp_init_irq_of(void) | |||
250 | { | 245 | { |
251 | cm_init(); | 246 | cm_init(); |
252 | of_irq_init(fpga_irq_of_match); | 247 | of_irq_init(fpga_irq_of_match); |
253 | integrator_clk_init(true); | ||
254 | } | 248 | } |
255 | 249 | ||
256 | /* | 250 | /* |
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 6e5077e2ec26..1c37082c8b39 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define CPU_RESET 0x00000002 | 22 | #define CPU_RESET 0x00000002 |
23 | 23 | ||
24 | #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) | 24 | #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) |
25 | #define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108) | ||
25 | #define SOFT_RESET_OUT_EN 0x00000004 | 26 | #define SOFT_RESET_OUT_EN 0x00000004 |
26 | 27 | ||
27 | #define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c) | 28 | #define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c) |
diff --git a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h index 5f03484584d4..e20d6da234a6 100644 --- a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h +++ b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #define L2_WRITETHROUGH 0x00020000 | 15 | #define L2_WRITETHROUGH 0x00020000 |
16 | 16 | ||
17 | #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) | 17 | #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) |
18 | #define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108) | ||
18 | #define SOFT_RESET_OUT_EN 0x00000004 | 19 | #define SOFT_RESET_OUT_EN 0x00000004 |
19 | 20 | ||
20 | #define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c) | 21 | #define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c) |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 5c22c0899e9c..cb31d4390d52 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -74,6 +74,7 @@ config SOC_DRA7XX | |||
74 | select ARM_CPU_SUSPEND if PM | 74 | select ARM_CPU_SUSPEND if PM |
75 | select ARM_GIC | 75 | select ARM_GIC |
76 | select HAVE_ARM_ARCH_TIMER | 76 | select HAVE_ARM_ARCH_TIMER |
77 | select IRQ_CROSSBAR | ||
77 | 78 | ||
78 | config ARCH_OMAP2PLUS | 79 | config ARCH_OMAP2PLUS |
79 | bool | 80 | bool |
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 3664562f9148..693fe486e917 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c | |||
@@ -138,7 +138,7 @@ static void wakeupgen_mask(struct irq_data *d) | |||
138 | unsigned long flags; | 138 | unsigned long flags; |
139 | 139 | ||
140 | raw_spin_lock_irqsave(&wakeupgen_lock, flags); | 140 | raw_spin_lock_irqsave(&wakeupgen_lock, flags); |
141 | _wakeupgen_clear(d->irq, irq_target_cpu[d->irq]); | 141 | _wakeupgen_clear(d->hwirq, irq_target_cpu[d->hwirq]); |
142 | raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); | 142 | raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); |
143 | } | 143 | } |
144 | 144 | ||
@@ -150,7 +150,7 @@ static void wakeupgen_unmask(struct irq_data *d) | |||
150 | unsigned long flags; | 150 | unsigned long flags; |
151 | 151 | ||
152 | raw_spin_lock_irqsave(&wakeupgen_lock, flags); | 152 | raw_spin_lock_irqsave(&wakeupgen_lock, flags); |
153 | _wakeupgen_set(d->irq, irq_target_cpu[d->irq]); | 153 | _wakeupgen_set(d->hwirq, irq_target_cpu[d->hwirq]); |
154 | raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); | 154 | raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); |
155 | } | 155 | } |
156 | 156 | ||
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 6cd3f3772ecf..95e171a055f3 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | #include <linux/export.h> | 23 | #include <linux/export.h> |
24 | #include <linux/irqchip/arm-gic.h> | 24 | #include <linux/irqchip/arm-gic.h> |
25 | #include <linux/irqchip/irq-crossbar.h> | ||
25 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
26 | #include <linux/reboot.h> | 27 | #include <linux/reboot.h> |
27 | 28 | ||
@@ -288,5 +289,8 @@ void __init omap_gic_of_init(void) | |||
288 | 289 | ||
289 | skip_errata_init: | 290 | skip_errata_init: |
290 | omap_wakeupgen_init(); | 291 | omap_wakeupgen_init(); |
292 | #ifdef CONFIG_IRQ_CROSSBAR | ||
293 | irqcrossbar_init(); | ||
294 | #endif | ||
291 | irqchip_init(); | 295 | irqchip_init(); |
292 | } | 296 | } |
diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h index f727d03f1688..5766e3fbff69 100644 --- a/arch/arm/mach-orion5x/include/mach/bridge-regs.h +++ b/arch/arm/mach-orion5x/include/mach/bridge-regs.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE + 0x104) | 18 | #define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE + 0x104) |
19 | 19 | ||
20 | #define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE + 0x108) | 20 | #define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE + 0x108) |
21 | #define RSTOUTn_MASK_PHYS (ORION5X_BRIDGE_PHYS_BASE + 0x108) | ||
21 | 22 | ||
22 | #define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE + 0x10c) | 23 | #define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE + 0x10c) |
23 | 24 | ||
diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c index e6ab0cd5b286..bee0073c9b64 100644 --- a/arch/arm/mach-shmobile/clock-r7s72100.c +++ b/arch/arm/mach-shmobile/clock-r7s72100.c | |||
@@ -22,12 +22,15 @@ | |||
22 | #include <mach/common.h> | 22 | #include <mach/common.h> |
23 | #include <mach/r7s72100.h> | 23 | #include <mach/r7s72100.h> |
24 | 24 | ||
25 | /* registers */ | 25 | /* Frequency Control Registers */ |
26 | #define FRQCR 0xfcfe0010 | 26 | #define FRQCR 0xfcfe0010 |
27 | #define FRQCR2 0xfcfe0014 | 27 | #define FRQCR2 0xfcfe0014 |
28 | /* Standby Control Registers */ | ||
28 | #define STBCR3 0xfcfe0420 | 29 | #define STBCR3 0xfcfe0420 |
29 | #define STBCR4 0xfcfe0424 | 30 | #define STBCR4 0xfcfe0424 |
31 | #define STBCR7 0xfcfe0430 | ||
30 | #define STBCR9 0xfcfe0438 | 32 | #define STBCR9 0xfcfe0438 |
33 | #define STBCR10 0xfcfe043c | ||
31 | 34 | ||
32 | #define PLL_RATE 30 | 35 | #define PLL_RATE 30 |
33 | 36 | ||
@@ -67,7 +70,7 @@ static struct clk pll_clk = { | |||
67 | 70 | ||
68 | static unsigned long bus_recalc(struct clk *clk) | 71 | static unsigned long bus_recalc(struct clk *clk) |
69 | { | 72 | { |
70 | return clk->parent->rate * 2 / 3; | 73 | return clk->parent->rate / 3; |
71 | } | 74 | } |
72 | 75 | ||
73 | static struct sh_clk_ops bus_clk_ops = { | 76 | static struct sh_clk_ops bus_clk_ops = { |
@@ -145,15 +148,25 @@ struct clk div4_clks[DIV4_NR] = { | |||
145 | | CLK_ENABLE_ON_INIT), | 148 | | CLK_ENABLE_ON_INIT), |
146 | }; | 149 | }; |
147 | 150 | ||
148 | enum { MSTP97, MSTP96, MSTP95, MSTP94, | 151 | enum { |
152 | MSTP107, MSTP106, MSTP105, MSTP104, MSTP103, | ||
153 | MSTP97, MSTP96, MSTP95, MSTP94, | ||
154 | MSTP74, | ||
149 | MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, | 155 | MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, |
150 | MSTP33, MSTP_NR }; | 156 | MSTP33, MSTP_NR |
157 | }; | ||
151 | 158 | ||
152 | static struct clk mstp_clks[MSTP_NR] = { | 159 | static struct clk mstp_clks[MSTP_NR] = { |
160 | [MSTP107] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 7, 0), /* RSPI0 */ | ||
161 | [MSTP106] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 6, 0), /* RSPI1 */ | ||
162 | [MSTP105] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 5, 0), /* RSPI2 */ | ||
163 | [MSTP104] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 4, 0), /* RSPI3 */ | ||
164 | [MSTP103] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 3, 0), /* RSPI4 */ | ||
153 | [MSTP97] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 7, 0), /* RIIC0 */ | 165 | [MSTP97] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 7, 0), /* RIIC0 */ |
154 | [MSTP96] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 6, 0), /* RIIC1 */ | 166 | [MSTP96] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 6, 0), /* RIIC1 */ |
155 | [MSTP95] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 5, 0), /* RIIC2 */ | 167 | [MSTP95] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 5, 0), /* RIIC2 */ |
156 | [MSTP94] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 4, 0), /* RIIC3 */ | 168 | [MSTP94] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 4, 0), /* RIIC3 */ |
169 | [MSTP74] = SH_CLK_MSTP8(&peripheral1_clk, STBCR7, 4, 0), /* Ether */ | ||
157 | [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ | 170 | [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ |
158 | [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ | 171 | [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ |
159 | [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ | 172 | [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ |
@@ -176,6 +189,21 @@ static struct clk_lookup lookups[] = { | |||
176 | CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), | 189 | CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), |
177 | 190 | ||
178 | /* MSTP clocks */ | 191 | /* MSTP clocks */ |
192 | CLKDEV_DEV_ID("rspi-rz.0", &mstp_clks[MSTP107]), | ||
193 | CLKDEV_DEV_ID("rspi-rz.1", &mstp_clks[MSTP106]), | ||
194 | CLKDEV_DEV_ID("rspi-rz.2", &mstp_clks[MSTP105]), | ||
195 | CLKDEV_DEV_ID("rspi-rz.3", &mstp_clks[MSTP104]), | ||
196 | CLKDEV_DEV_ID("rspi-rz.4", &mstp_clks[MSTP103]), | ||
197 | CLKDEV_DEV_ID("e800c800.spi", &mstp_clks[MSTP107]), | ||
198 | CLKDEV_DEV_ID("e800d000.spi", &mstp_clks[MSTP106]), | ||
199 | CLKDEV_DEV_ID("e800d800.spi", &mstp_clks[MSTP105]), | ||
200 | CLKDEV_DEV_ID("e800e000.spi", &mstp_clks[MSTP104]), | ||
201 | CLKDEV_DEV_ID("e800e800.spi", &mstp_clks[MSTP103]), | ||
202 | CLKDEV_DEV_ID("fcfee000.i2c", &mstp_clks[MSTP97]), | ||
203 | CLKDEV_DEV_ID("fcfee400.i2c", &mstp_clks[MSTP96]), | ||
204 | CLKDEV_DEV_ID("fcfee800.i2c", &mstp_clks[MSTP95]), | ||
205 | CLKDEV_DEV_ID("fcfeec00.i2c", &mstp_clks[MSTP94]), | ||
206 | CLKDEV_DEV_ID("r7s72100-ether", &mstp_clks[MSTP74]), | ||
179 | CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP33]), | 207 | CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP33]), |
180 | 208 | ||
181 | /* ICK */ | 209 | /* ICK */ |
diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index 9783945f8bc7..2009a9bc6356 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c | |||
@@ -221,6 +221,10 @@ static struct clk_lookup lookups[] = { | |||
221 | CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */ | 221 | CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */ |
222 | CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */ | 222 | CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */ |
223 | 223 | ||
224 | CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a), | ||
225 | CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b), | ||
226 | CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c), | ||
227 | CLKDEV_ICK_ID("clk_i", "rcar_sound", &s1_clk), | ||
224 | CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]), | 228 | CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]), |
225 | CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]), | 229 | CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]), |
226 | CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]), | 230 | CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]), |
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index cabedebd7648..8e403ae0c7b2 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c | |||
@@ -120,16 +120,16 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
120 | [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */ | 120 | [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */ |
121 | [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */ | 121 | [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */ |
122 | [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */ | 122 | [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */ |
123 | [MSTP120] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 20, 0), /* VIN3 */ | 123 | [MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */ |
124 | [MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */ | 124 | [MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */ |
125 | [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */ | 125 | [MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */ |
126 | [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */ | 126 | [MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */ |
127 | [MSTP110] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 10, 0), /* VIN0 */ | 127 | [MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */ |
128 | [MSTP109] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 9, 0), /* VIN1 */ | 128 | [MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 9, MSTPSR1, 0), /* VIN1 */ |
129 | [MSTP108] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 8, 0), /* VIN2 */ | 129 | [MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 8, MSTPSR1, 0), /* VIN2 */ |
130 | [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */ | 130 | [MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 3, MSTPSR1, 0), /* DU */ |
131 | [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */ | 131 | [MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 1, MSTPSR1, 0), /* USB2 */ |
132 | [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */ | 132 | [MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 0, MSTPSR1, 0), /* USB0/1 */ |
133 | [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */ | 133 | [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */ |
134 | [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */ | 134 | [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */ |
135 | [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */ | 135 | [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */ |
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index f44987a92ad4..3f93503f5b96 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c | |||
@@ -43,17 +43,26 @@ | |||
43 | * see "p1 / 2" on R8A7790_CLOCK_ROOT() below | 43 | * see "p1 / 2" on R8A7790_CLOCK_ROOT() below |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #define CPG_BASE 0xe6150000 | 46 | #define CPG_BASE 0xe6150000 |
47 | #define CPG_LEN 0x1000 | 47 | #define CPG_LEN 0x1000 |
48 | 48 | ||
49 | #define SMSTPCR1 0xe6150134 | 49 | #define SMSTPCR1 0xe6150134 |
50 | #define SMSTPCR2 0xe6150138 | 50 | #define SMSTPCR2 0xe6150138 |
51 | #define SMSTPCR3 0xe615013c | 51 | #define SMSTPCR3 0xe615013c |
52 | #define SMSTPCR5 0xe6150144 | 52 | #define SMSTPCR5 0xe6150144 |
53 | #define SMSTPCR7 0xe615014c | 53 | #define SMSTPCR7 0xe615014c |
54 | #define SMSTPCR8 0xe6150990 | 54 | #define SMSTPCR8 0xe6150990 |
55 | #define SMSTPCR9 0xe6150994 | 55 | #define SMSTPCR9 0xe6150994 |
56 | #define SMSTPCR10 0xe6150998 | 56 | #define SMSTPCR10 0xe6150998 |
57 | |||
58 | #define MSTPSR1 IOMEM(0xe6150038) | ||
59 | #define MSTPSR2 IOMEM(0xe6150040) | ||
60 | #define MSTPSR3 IOMEM(0xe6150048) | ||
61 | #define MSTPSR5 IOMEM(0xe615003c) | ||
62 | #define MSTPSR7 IOMEM(0xe61501c4) | ||
63 | #define MSTPSR8 IOMEM(0xe61509a0) | ||
64 | #define MSTPSR9 IOMEM(0xe61509a4) | ||
65 | #define MSTPSR10 IOMEM(0xe61509a8) | ||
57 | 66 | ||
58 | #define SDCKCR 0xE6150074 | 67 | #define SDCKCR 0xE6150074 |
59 | #define SD2CKCR 0xE6150078 | 68 | #define SD2CKCR 0xE6150078 |
@@ -82,6 +91,15 @@ static struct clk main_clk = { | |||
82 | .ops = &followparent_clk_ops, | 91 | .ops = &followparent_clk_ops, |
83 | }; | 92 | }; |
84 | 93 | ||
94 | static struct clk audio_clk_a = { | ||
95 | }; | ||
96 | |||
97 | static struct clk audio_clk_b = { | ||
98 | }; | ||
99 | |||
100 | static struct clk audio_clk_c = { | ||
101 | }; | ||
102 | |||
85 | /* | 103 | /* |
86 | * clock ratio of these clock will be updated | 104 | * clock ratio of these clock will be updated |
87 | * on r8a7790_clock_init() | 105 | * on r8a7790_clock_init() |
@@ -115,6 +133,9 @@ SH_FIXED_RATIO_CLK_SET(ddr_clk, pll3_clk, 1, 8); | |||
115 | SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); | 133 | SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); |
116 | 134 | ||
117 | static struct clk *main_clks[] = { | 135 | static struct clk *main_clks[] = { |
136 | &audio_clk_a, | ||
137 | &audio_clk_b, | ||
138 | &audio_clk_c, | ||
118 | &extal_clk, | 139 | &extal_clk, |
119 | &extal_div2_clk, | 140 | &extal_div2_clk, |
120 | &main_clk, | 141 | &main_clk, |
@@ -183,15 +204,22 @@ static struct clk div6_clks[DIV6_NR] = { | |||
183 | 204 | ||
184 | /* MSTP */ | 205 | /* MSTP */ |
185 | enum { | 206 | enum { |
207 | MSTP1017, /* parent of SCU */ | ||
208 | |||
209 | MSTP1031, MSTP1030, | ||
210 | MSTP1029, MSTP1028, MSTP1027, MSTP1026, MSTP1025, MSTP1024, MSTP1023, MSTP1022, | ||
186 | MSTP1015, MSTP1014, MSTP1013, MSTP1012, MSTP1011, MSTP1010, | 211 | MSTP1015, MSTP1014, MSTP1013, MSTP1012, MSTP1011, MSTP1010, |
187 | MSTP1009, MSTP1008, MSTP1007, MSTP1006, MSTP1005, | 212 | MSTP1009, MSTP1008, MSTP1007, MSTP1006, MSTP1005, |
188 | MSTP931, MSTP930, MSTP929, MSTP928, | 213 | MSTP931, MSTP930, MSTP929, MSTP928, |
189 | MSTP917, | 214 | MSTP917, |
215 | MSTP815, MSTP814, | ||
190 | MSTP813, | 216 | MSTP813, |
217 | MSTP811, MSTP810, MSTP809, MSTP808, | ||
191 | MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720, | 218 | MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720, |
192 | MSTP717, MSTP716, | 219 | MSTP717, MSTP716, |
193 | MSTP704, | 220 | MSTP704, MSTP703, |
194 | MSTP522, | 221 | MSTP522, |
222 | MSTP502, MSTP501, | ||
195 | MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304, | 223 | MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304, |
196 | MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, | 224 | MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, |
197 | MSTP124, | 225 | MSTP124, |
@@ -199,53 +227,77 @@ enum { | |||
199 | }; | 227 | }; |
200 | 228 | ||
201 | static struct clk mstp_clks[MSTP_NR] = { | 229 | static struct clk mstp_clks[MSTP_NR] = { |
202 | [MSTP1015] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 15, 0), /* SSI0 */ | 230 | [MSTP1031] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 31, MSTPSR10, 0), /* SCU0 */ |
203 | [MSTP1014] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 14, 0), /* SSI1 */ | 231 | [MSTP1030] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 30, MSTPSR10, 0), /* SCU1 */ |
204 | [MSTP1013] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 13, 0), /* SSI2 */ | 232 | [MSTP1029] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 29, MSTPSR10, 0), /* SCU2 */ |
205 | [MSTP1012] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 12, 0), /* SSI3 */ | 233 | [MSTP1028] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 28, MSTPSR10, 0), /* SCU3 */ |
206 | [MSTP1011] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 11, 0), /* SSI4 */ | 234 | [MSTP1027] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 27, MSTPSR10, 0), /* SCU4 */ |
207 | [MSTP1010] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 10, 0), /* SSI5 */ | 235 | [MSTP1026] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 26, MSTPSR10, 0), /* SCU5 */ |
208 | [MSTP1009] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 9, 0), /* SSI6 */ | 236 | [MSTP1025] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 25, MSTPSR10, 0), /* SCU6 */ |
209 | [MSTP1008] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 8, 0), /* SSI7 */ | 237 | [MSTP1024] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 24, MSTPSR10, 0), /* SCU7 */ |
210 | [MSTP1007] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 7, 0), /* SSI8 */ | 238 | [MSTP1023] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 23, MSTPSR10, 0), /* SCU8 */ |
211 | [MSTP1006] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 6, 0), /* SSI9 */ | 239 | [MSTP1022] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 22, MSTPSR10, 0), /* SCU9 */ |
212 | [MSTP1005] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 5, 0), /* SSI ALL */ | 240 | [MSTP1017] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 17, MSTPSR10, 0), /* SCU */ |
213 | [MSTP931] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 31, 0), /* I2C0 */ | 241 | [MSTP1015] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 15, MSTPSR10, 0), /* SSI0 */ |
214 | [MSTP930] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 30, 0), /* I2C1 */ | 242 | [MSTP1014] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 14, MSTPSR10, 0), /* SSI1 */ |
215 | [MSTP929] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 29, 0), /* I2C2 */ | 243 | [MSTP1013] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 13, MSTPSR10, 0), /* SSI2 */ |
216 | [MSTP928] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 28, 0), /* I2C3 */ | 244 | [MSTP1012] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 12, MSTPSR10, 0), /* SSI3 */ |
217 | [MSTP917] = SH_CLK_MSTP32(&qspi_clk, SMSTPCR9, 17, 0), /* QSPI */ | 245 | [MSTP1011] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 11, MSTPSR10, 0), /* SSI4 */ |
218 | [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */ | 246 | [MSTP1010] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 10, MSTPSR10, 0), /* SSI5 */ |
219 | [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */ | 247 | [MSTP1009] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 9, MSTPSR10, 0), /* SSI6 */ |
220 | [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */ | 248 | [MSTP1008] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 8, MSTPSR10, 0), /* SSI7 */ |
221 | [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */ | 249 | [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */ |
222 | [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */ | 250 | [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */ |
223 | [MSTP722] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 22, 0), /* DU2 */ | 251 | [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */ |
224 | [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ | 252 | [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ |
225 | [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ | 253 | [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ |
226 | [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */ | 254 | [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ |
227 | [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */ | 255 | [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ |
228 | [MSTP704] = SH_CLK_MSTP32(&mp_clk, SMSTPCR7, 4, 0), /* HSUSB */ | 256 | [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ |
229 | [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */ | 257 | [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ |
230 | [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */ | 258 | [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ |
231 | [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */ | 259 | [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */ |
232 | [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_SD1], SMSTPCR3, 13, 0), /* SDHI1 */ | 260 | [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */ |
233 | [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SD2], SMSTPCR3, 12, 0), /* SDHI2 */ | 261 | [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */ |
234 | [MSTP311] = SH_CLK_MSTP32(&div6_clks[DIV6_SD3], SMSTPCR3, 11, 0), /* SDHI3 */ | 262 | [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */ |
235 | [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, 0), /* MMC1 */ | 263 | [MSTP808] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 8, MSTPSR8, 0), /* VIN3 */ |
236 | [MSTP304] = SH_CLK_MSTP32(&cp_clk, SMSTPCR3, 4, 0), /* TPU0 */ | 264 | [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */ |
237 | [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ | 265 | [MSTP725] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 25, MSTPSR7, 0), /* LVDS1 */ |
238 | [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ | 266 | [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */ |
239 | [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ | 267 | [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */ |
240 | [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ | 268 | [MSTP722] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 22, MSTPSR7, 0), /* DU2 */ |
241 | [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ | 269 | [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */ |
242 | [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ | 270 | [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */ |
243 | [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */ | 271 | [MSTP717] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 17, MSTPSR7, 0), /* HSCIF0 */ |
272 | [MSTP716] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 16, MSTPSR7, 0), /* HSCIF1 */ | ||
273 | [MSTP704] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 4, MSTPSR7, 0), /* HSUSB */ | ||
274 | [MSTP703] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 3, MSTPSR7, 0), /* EHCI */ | ||
275 | [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */ | ||
276 | [MSTP502] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 2, MSTPSR5, 0), /* Audio-DMAC low */ | ||
277 | [MSTP501] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 1, MSTPSR5, 0), /* Audio-DMAC hi */ | ||
278 | [MSTP315] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, MSTPSR3, 0), /* MMC0 */ | ||
279 | [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */ | ||
280 | [MSTP313] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD1], SMSTPCR3, 13, MSTPSR3, 0), /* SDHI1 */ | ||
281 | [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI2 */ | ||
282 | [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD3], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI3 */ | ||
283 | [MSTP305] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, MSTPSR3, 0), /* MMC1 */ | ||
284 | [MSTP304] = SH_CLK_MSTP32_STS(&cp_clk, SMSTPCR3, 4, MSTPSR3, 0), /* TPU0 */ | ||
285 | [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */ | ||
286 | [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */ | ||
287 | [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */ | ||
288 | [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */ | ||
289 | [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */ | ||
290 | [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */ | ||
291 | [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */ | ||
244 | }; | 292 | }; |
245 | 293 | ||
246 | static struct clk_lookup lookups[] = { | 294 | static struct clk_lookup lookups[] = { |
247 | 295 | ||
248 | /* main clocks */ | 296 | /* main clocks */ |
297 | CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), | ||
298 | CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), | ||
299 | CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), | ||
300 | CLKDEV_CON_ID("audio_clk_internal", &m2_clk), | ||
249 | CLKDEV_CON_ID("extal", &extal_clk), | 301 | CLKDEV_CON_ID("extal", &extal_clk), |
250 | CLKDEV_CON_ID("extal_div2", &extal_div2_clk), | 302 | CLKDEV_CON_ID("extal_div2", &extal_div2_clk), |
251 | CLKDEV_CON_ID("main", &main_clk), | 303 | CLKDEV_CON_ID("main", &main_clk), |
@@ -291,32 +343,32 @@ static struct clk_lookup lookups[] = { | |||
291 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), | 343 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), |
292 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]), | 344 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]), |
293 | CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]), | 345 | CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]), |
294 | CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]), | ||
295 | CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]), | 346 | CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]), |
296 | CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]), | ||
297 | CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]), | 347 | CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]), |
298 | CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]), | ||
299 | CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]), | 348 | CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]), |
300 | CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]), | ||
301 | CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]), | 349 | CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]), |
302 | CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]), | 350 | CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]), |
303 | CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]), | 351 | CLKDEV_DEV_ID("r8a7790-vin.0", &mstp_clks[MSTP811]), |
352 | CLKDEV_DEV_ID("r8a7790-vin.1", &mstp_clks[MSTP810]), | ||
353 | CLKDEV_DEV_ID("r8a7790-vin.2", &mstp_clks[MSTP809]), | ||
354 | CLKDEV_DEV_ID("r8a7790-vin.3", &mstp_clks[MSTP808]), | ||
304 | CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), | 355 | CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), |
305 | CLKDEV_DEV_ID("ee200000.mmc", &mstp_clks[MSTP315]), | 356 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP502]), |
357 | CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP501]), | ||
306 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), | 358 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), |
307 | CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), | ||
308 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), | 359 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), |
309 | CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), | ||
310 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), | 360 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), |
311 | CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]), | ||
312 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), | 361 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), |
313 | CLKDEV_DEV_ID("ee160000.sd", &mstp_clks[MSTP311]), | ||
314 | CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]), | 362 | CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]), |
315 | CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]), | ||
316 | CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), | 363 | CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), |
317 | CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), | 364 | CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), |
318 | CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]), | 365 | CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]), |
319 | CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]), | 366 | CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]), |
367 | CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]), | ||
368 | CLKDEV_DEV_ID("pci-rcar-gen2.1", &mstp_clks[MSTP703]), | ||
369 | CLKDEV_DEV_ID("pci-rcar-gen2.2", &mstp_clks[MSTP703]), | ||
370 | CLKDEV_DEV_ID("sata-r8a7790.0", &mstp_clks[MSTP815]), | ||
371 | CLKDEV_DEV_ID("sata-r8a7790.1", &mstp_clks[MSTP814]), | ||
320 | 372 | ||
321 | /* ICK */ | 373 | /* ICK */ |
322 | CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]), | 374 | CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]), |
@@ -325,6 +377,20 @@ static struct clk_lookup lookups[] = { | |||
325 | CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]), | 377 | CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]), |
326 | CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]), | 378 | CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]), |
327 | CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]), | 379 | CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]), |
380 | CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a), | ||
381 | CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b), | ||
382 | CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c), | ||
383 | CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk), | ||
384 | CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP1031]), | ||
385 | CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP1030]), | ||
386 | CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP1029]), | ||
387 | CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP1028]), | ||
388 | CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP1027]), | ||
389 | CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP1026]), | ||
390 | CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP1025]), | ||
391 | CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP1024]), | ||
392 | CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP1023]), | ||
393 | CLKDEV_ICK_ID("scu.9", "rcar_sound", &mstp_clks[MSTP1022]), | ||
328 | CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]), | 394 | CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]), |
329 | CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]), | 395 | CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]), |
330 | CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]), | 396 | CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]), |
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c index f5461262ee25..701383fe3267 100644 --- a/arch/arm/mach-shmobile/clock-r8a7791.c +++ b/arch/arm/mach-shmobile/clock-r8a7791.c | |||
@@ -59,10 +59,19 @@ | |||
59 | #define SMSTPCR10 0xE6150998 | 59 | #define SMSTPCR10 0xE6150998 |
60 | #define SMSTPCR11 0xE615099C | 60 | #define SMSTPCR11 0xE615099C |
61 | 61 | ||
62 | #define MSTPSR1 IOMEM(0xe6150038) | ||
63 | #define MSTPSR2 IOMEM(0xe6150040) | ||
64 | #define MSTPSR3 IOMEM(0xe6150048) | ||
65 | #define MSTPSR5 IOMEM(0xe615003c) | ||
66 | #define MSTPSR7 IOMEM(0xe61501c4) | ||
67 | #define MSTPSR8 IOMEM(0xe61509a0) | ||
68 | #define MSTPSR9 IOMEM(0xe61509a4) | ||
69 | #define MSTPSR11 IOMEM(0xe61509ac) | ||
70 | |||
62 | #define MODEMR 0xE6160060 | 71 | #define MODEMR 0xE6160060 |
63 | #define SDCKCR 0xE6150074 | 72 | #define SDCKCR 0xE6150074 |
64 | #define SD2CKCR 0xE6150078 | 73 | #define SD1CKCR 0xE6150078 |
65 | #define SD3CKCR 0xE615007C | 74 | #define SD2CKCR 0xE615026c |
66 | #define MMC0CKCR 0xE6150240 | 75 | #define MMC0CKCR 0xE6150240 |
67 | #define MMC1CKCR 0xE6150244 | 76 | #define MMC1CKCR 0xE6150244 |
68 | #define SSPCKCR 0xE6150248 | 77 | #define SSPCKCR 0xE6150248 |
@@ -93,6 +102,7 @@ static struct clk main_clk = { | |||
93 | */ | 102 | */ |
94 | SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); | 103 | SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); |
95 | SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); | 104 | SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); |
105 | SH_FIXED_RATIO_CLK_SET(qspi_clk, pll1_clk, 1, 1); | ||
96 | 106 | ||
97 | /* fixed ratio clock */ | 107 | /* fixed ratio clock */ |
98 | SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); | 108 | SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); |
@@ -103,7 +113,9 @@ SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); | |||
103 | SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); | 113 | SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); |
104 | SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); | 114 | SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); |
105 | SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); | 115 | SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); |
116 | SH_FIXED_RATIO_CLK_SET(zg_clk, pll1_clk, 1, 3); | ||
106 | SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3); | 117 | SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3); |
118 | SH_FIXED_RATIO_CLK_SET(zs_clk, pll1_clk, 1, 6); | ||
107 | 119 | ||
108 | static struct clk *main_clks[] = { | 120 | static struct clk *main_clks[] = { |
109 | &extal_clk, | 121 | &extal_clk, |
@@ -114,46 +126,103 @@ static struct clk *main_clks[] = { | |||
114 | &pll3_clk, | 126 | &pll3_clk, |
115 | &hp_clk, | 127 | &hp_clk, |
116 | &p_clk, | 128 | &p_clk, |
129 | &qspi_clk, | ||
117 | &rclk_clk, | 130 | &rclk_clk, |
118 | &mp_clk, | 131 | &mp_clk, |
119 | &cp_clk, | 132 | &cp_clk, |
133 | &zg_clk, | ||
120 | &zx_clk, | 134 | &zx_clk, |
135 | &zs_clk, | ||
136 | }; | ||
137 | |||
138 | /* SDHI (DIV4) clock */ | ||
139 | static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 }; | ||
140 | |||
141 | static struct clk_div_mult_table div4_div_mult_table = { | ||
142 | .divisors = divisors, | ||
143 | .nr_divisors = ARRAY_SIZE(divisors), | ||
144 | }; | ||
145 | |||
146 | static struct clk_div4_table div4_table = { | ||
147 | .div_mult_table = &div4_div_mult_table, | ||
148 | }; | ||
149 | |||
150 | enum { | ||
151 | DIV4_SDH, DIV4_SD0, | ||
152 | DIV4_NR | ||
153 | }; | ||
154 | |||
155 | static struct clk div4_clks[DIV4_NR] = { | ||
156 | [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT), | ||
157 | [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT), | ||
158 | }; | ||
159 | |||
160 | /* DIV6 clocks */ | ||
161 | enum { | ||
162 | DIV6_SD1, DIV6_SD2, | ||
163 | DIV6_NR | ||
164 | }; | ||
165 | |||
166 | static struct clk div6_clks[DIV6_NR] = { | ||
167 | [DIV6_SD1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0), | ||
168 | [DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0), | ||
121 | }; | 169 | }; |
122 | 170 | ||
123 | /* MSTP */ | 171 | /* MSTP */ |
124 | enum { | 172 | enum { |
173 | MSTP1108, MSTP1107, MSTP1106, | ||
174 | MSTP931, MSTP930, MSTP929, MSTP928, MSTP927, MSTP925, | ||
175 | MSTP917, | ||
176 | MSTP815, MSTP814, | ||
125 | MSTP813, | 177 | MSTP813, |
178 | MSTP811, MSTP810, MSTP809, | ||
126 | MSTP726, MSTP724, MSTP723, MSTP721, MSTP720, | 179 | MSTP726, MSTP724, MSTP723, MSTP721, MSTP720, |
127 | MSTP719, MSTP718, MSTP715, MSTP714, | 180 | MSTP719, MSTP718, MSTP715, MSTP714, |
128 | MSTP522, | 181 | MSTP522, |
182 | MSTP314, MSTP312, MSTP311, | ||
129 | MSTP216, MSTP207, MSTP206, | 183 | MSTP216, MSTP207, MSTP206, |
130 | MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107, | 184 | MSTP204, MSTP203, MSTP202, |
131 | MSTP124, | 185 | MSTP124, |
132 | MSTP_NR | 186 | MSTP_NR |
133 | }; | 187 | }; |
134 | 188 | ||
135 | static struct clk mstp_clks[MSTP_NR] = { | 189 | static struct clk mstp_clks[MSTP_NR] = { |
136 | [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */ | 190 | [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */ |
137 | [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */ | 191 | [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */ |
138 | [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */ | 192 | [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */ |
139 | [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */ | 193 | [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ |
140 | [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ | 194 | [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ |
141 | [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ | 195 | [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ |
142 | [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */ | 196 | [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ |
143 | [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */ | 197 | [MSTP927] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */ |
144 | [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */ | 198 | [MSTP925] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */ |
145 | [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */ | 199 | [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ |
146 | [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */ | 200 | [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ |
147 | [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ | 201 | [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ |
148 | [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ | 202 | [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */ |
149 | [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ | 203 | [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */ |
150 | [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ | 204 | [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */ |
151 | [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ | 205 | [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */ |
152 | [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ | 206 | [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */ |
153 | [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */ | 207 | [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */ |
154 | [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */ | 208 | [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */ |
155 | [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */ | 209 | [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */ |
156 | [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */ | 210 | [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */ |
211 | [MSTP719] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 19, MSTPSR7, 0), /* SCIF2 */ | ||
212 | [MSTP718] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 18, MSTPSR7, 0), /* SCIF3 */ | ||
213 | [MSTP715] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 15, MSTPSR7, 0), /* SCIF4 */ | ||
214 | [MSTP714] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 14, MSTPSR7, 0), /* SCIF5 */ | ||
215 | [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */ | ||
216 | [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */ | ||
217 | [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD1], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI1 */ | ||
218 | [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI2 */ | ||
219 | [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */ | ||
220 | [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */ | ||
221 | [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */ | ||
222 | [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */ | ||
223 | [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */ | ||
224 | [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */ | ||
225 | [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */ | ||
157 | }; | 226 | }; |
158 | 227 | ||
159 | static struct clk_lookup lookups[] = { | 228 | static struct clk_lookup lookups[] = { |
@@ -165,8 +234,11 @@ static struct clk_lookup lookups[] = { | |||
165 | CLKDEV_CON_ID("pll1", &pll1_clk), | 234 | CLKDEV_CON_ID("pll1", &pll1_clk), |
166 | CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), | 235 | CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), |
167 | CLKDEV_CON_ID("pll3", &pll3_clk), | 236 | CLKDEV_CON_ID("pll3", &pll3_clk), |
237 | CLKDEV_CON_ID("zg", &zg_clk), | ||
238 | CLKDEV_CON_ID("zs", &zs_clk), | ||
168 | CLKDEV_CON_ID("hp", &hp_clk), | 239 | CLKDEV_CON_ID("hp", &hp_clk), |
169 | CLKDEV_CON_ID("p", &p_clk), | 240 | CLKDEV_CON_ID("p", &p_clk), |
241 | CLKDEV_CON_ID("qspi", &qspi_clk), | ||
170 | CLKDEV_CON_ID("rclk", &rclk_clk), | 242 | CLKDEV_CON_ID("rclk", &rclk_clk), |
171 | CLKDEV_CON_ID("mp", &mp_clk), | 243 | CLKDEV_CON_ID("mp", &mp_clk), |
172 | CLKDEV_CON_ID("cp", &cp_clk), | 244 | CLKDEV_CON_ID("cp", &cp_clk), |
@@ -188,13 +260,27 @@ static struct clk_lookup lookups[] = { | |||
188 | CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */ | 260 | CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */ |
189 | CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */ | 261 | CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */ |
190 | CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */ | 262 | CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */ |
191 | CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */ | 263 | CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1106]), /* SCIFA3 */ |
192 | CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */ | 264 | CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1107]), /* SCIFA4 */ |
193 | CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */ | 265 | CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1108]), /* SCIFA5 */ |
266 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), | ||
267 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP312]), | ||
268 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), | ||
194 | CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), | 269 | CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), |
195 | CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]), | 270 | CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]), |
196 | CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), | 271 | CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), |
272 | CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]), | ||
273 | CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]), | ||
274 | CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]), | ||
275 | CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]), | ||
276 | CLKDEV_DEV_ID("i2c-rcar_gen2.4", &mstp_clks[MSTP927]), | ||
277 | CLKDEV_DEV_ID("i2c-rcar_gen2.5", &mstp_clks[MSTP925]), | ||
197 | CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */ | 278 | CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */ |
279 | CLKDEV_DEV_ID("r8a7791-vin.0", &mstp_clks[MSTP811]), | ||
280 | CLKDEV_DEV_ID("r8a7791-vin.1", &mstp_clks[MSTP810]), | ||
281 | CLKDEV_DEV_ID("r8a7791-vin.2", &mstp_clks[MSTP809]), | ||
282 | CLKDEV_DEV_ID("sata-r8a7791.0", &mstp_clks[MSTP815]), | ||
283 | CLKDEV_DEV_ID("sata-r8a7791.1", &mstp_clks[MSTP814]), | ||
198 | }; | 284 | }; |
199 | 285 | ||
200 | #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ | 286 | #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ |
@@ -232,10 +318,21 @@ void __init r8a7791_clock_init(void) | |||
232 | break; | 318 | break; |
233 | } | 319 | } |
234 | 320 | ||
321 | if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2)) | ||
322 | SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16); | ||
323 | else | ||
324 | SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20); | ||
325 | |||
235 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) | 326 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) |
236 | ret = clk_register(main_clks[k]); | 327 | ret = clk_register(main_clks[k]); |
237 | 328 | ||
238 | if (!ret) | 329 | if (!ret) |
330 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | ||
331 | |||
332 | if (!ret) | ||
333 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | ||
334 | |||
335 | if (!ret) | ||
239 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); | 336 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
240 | 337 | ||
241 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 338 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 3389f0775def..0b95babe84ba 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h | |||
@@ -3,6 +3,31 @@ | |||
3 | 3 | ||
4 | #include <mach/rcar-gen2.h> | 4 | #include <mach/rcar-gen2.h> |
5 | 5 | ||
6 | /* DMA slave IDs */ | ||
7 | enum { | ||
8 | RCAR_DMA_SLAVE_INVALID, | ||
9 | AUDIO_DMAC_SLAVE_SSI0_TX, | ||
10 | AUDIO_DMAC_SLAVE_SSI0_RX, | ||
11 | AUDIO_DMAC_SLAVE_SSI1_TX, | ||
12 | AUDIO_DMAC_SLAVE_SSI1_RX, | ||
13 | AUDIO_DMAC_SLAVE_SSI2_TX, | ||
14 | AUDIO_DMAC_SLAVE_SSI2_RX, | ||
15 | AUDIO_DMAC_SLAVE_SSI3_TX, | ||
16 | AUDIO_DMAC_SLAVE_SSI3_RX, | ||
17 | AUDIO_DMAC_SLAVE_SSI4_TX, | ||
18 | AUDIO_DMAC_SLAVE_SSI4_RX, | ||
19 | AUDIO_DMAC_SLAVE_SSI5_TX, | ||
20 | AUDIO_DMAC_SLAVE_SSI5_RX, | ||
21 | AUDIO_DMAC_SLAVE_SSI6_TX, | ||
22 | AUDIO_DMAC_SLAVE_SSI6_RX, | ||
23 | AUDIO_DMAC_SLAVE_SSI7_TX, | ||
24 | AUDIO_DMAC_SLAVE_SSI7_RX, | ||
25 | AUDIO_DMAC_SLAVE_SSI8_TX, | ||
26 | AUDIO_DMAC_SLAVE_SSI8_RX, | ||
27 | AUDIO_DMAC_SLAVE_SSI9_TX, | ||
28 | AUDIO_DMAC_SLAVE_SSI9_RX, | ||
29 | }; | ||
30 | |||
6 | void r8a7790_add_standard_devices(void); | 31 | void r8a7790_add_standard_devices(void); |
7 | void r8a7790_add_dt_devices(void); | 32 | void r8a7790_add_dt_devices(void); |
8 | void r8a7790_clock_init(void); | 33 | void r8a7790_clock_init(void); |
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 6ab37aa1e919..c4616f0698c6 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c | |||
@@ -24,12 +24,100 @@ | |||
24 | #include <linux/platform_data/gpio-rcar.h> | 24 | #include <linux/platform_data/gpio-rcar.h> |
25 | #include <linux/platform_data/irq-renesas-irqc.h> | 25 | #include <linux/platform_data/irq-renesas-irqc.h> |
26 | #include <linux/serial_sci.h> | 26 | #include <linux/serial_sci.h> |
27 | #include <linux/sh_dma.h> | ||
27 | #include <linux/sh_timer.h> | 28 | #include <linux/sh_timer.h> |
28 | #include <mach/common.h> | 29 | #include <mach/common.h> |
30 | #include <mach/dma-register.h> | ||
29 | #include <mach/irqs.h> | 31 | #include <mach/irqs.h> |
30 | #include <mach/r8a7790.h> | 32 | #include <mach/r8a7790.h> |
31 | #include <asm/mach/arch.h> | 33 | #include <asm/mach/arch.h> |
32 | 34 | ||
35 | /* Audio-DMAC */ | ||
36 | #define AUDIO_DMAC_SLAVE(_id, _addr, t, r) \ | ||
37 | { \ | ||
38 | .slave_id = AUDIO_DMAC_SLAVE_## _id ##_TX, \ | ||
39 | .addr = _addr + 0x8, \ | ||
40 | .chcr = CHCR_TX(XMIT_SZ_32BIT), \ | ||
41 | .mid_rid = t, \ | ||
42 | }, { \ | ||
43 | .slave_id = AUDIO_DMAC_SLAVE_## _id ##_RX, \ | ||
44 | .addr = _addr + 0xc, \ | ||
45 | .chcr = CHCR_RX(XMIT_SZ_32BIT), \ | ||
46 | .mid_rid = r, \ | ||
47 | } | ||
48 | |||
49 | static const struct sh_dmae_slave_config r8a7790_audio_dmac_slaves[] = { | ||
50 | AUDIO_DMAC_SLAVE(SSI0, 0xec241000, 0x01, 0x02), | ||
51 | AUDIO_DMAC_SLAVE(SSI1, 0xec241040, 0x03, 0x04), | ||
52 | AUDIO_DMAC_SLAVE(SSI2, 0xec241080, 0x05, 0x06), | ||
53 | AUDIO_DMAC_SLAVE(SSI3, 0xec2410c0, 0x07, 0x08), | ||
54 | AUDIO_DMAC_SLAVE(SSI4, 0xec241100, 0x09, 0x0a), | ||
55 | AUDIO_DMAC_SLAVE(SSI5, 0xec241140, 0x0b, 0x0c), | ||
56 | AUDIO_DMAC_SLAVE(SSI6, 0xec241180, 0x0d, 0x0e), | ||
57 | AUDIO_DMAC_SLAVE(SSI7, 0xec2411c0, 0x0f, 0x10), | ||
58 | AUDIO_DMAC_SLAVE(SSI8, 0xec241200, 0x11, 0x12), | ||
59 | AUDIO_DMAC_SLAVE(SSI9, 0xec241240, 0x13, 0x14), | ||
60 | }; | ||
61 | |||
62 | #define DMAE_CHANNEL(a, b) \ | ||
63 | { \ | ||
64 | .offset = (a) - 0x20, \ | ||
65 | .dmars = (a) - 0x20 + 0x40, \ | ||
66 | .chclr_bit = (b), \ | ||
67 | .chclr_offset = 0x80 - 0x20, \ | ||
68 | } | ||
69 | |||
70 | static const struct sh_dmae_channel r8a7790_audio_dmac_channels[] = { | ||
71 | DMAE_CHANNEL(0x8000, 0), | ||
72 | DMAE_CHANNEL(0x8080, 1), | ||
73 | DMAE_CHANNEL(0x8100, 2), | ||
74 | DMAE_CHANNEL(0x8180, 3), | ||
75 | DMAE_CHANNEL(0x8200, 4), | ||
76 | DMAE_CHANNEL(0x8280, 5), | ||
77 | DMAE_CHANNEL(0x8300, 6), | ||
78 | DMAE_CHANNEL(0x8380, 7), | ||
79 | DMAE_CHANNEL(0x8400, 8), | ||
80 | DMAE_CHANNEL(0x8480, 9), | ||
81 | DMAE_CHANNEL(0x8500, 10), | ||
82 | DMAE_CHANNEL(0x8580, 11), | ||
83 | DMAE_CHANNEL(0x8600, 12), | ||
84 | }; | ||
85 | |||
86 | static struct sh_dmae_pdata r8a7790_audio_dmac_platform_data = { | ||
87 | .slave = r8a7790_audio_dmac_slaves, | ||
88 | .slave_num = ARRAY_SIZE(r8a7790_audio_dmac_slaves), | ||
89 | .channel = r8a7790_audio_dmac_channels, | ||
90 | .channel_num = ARRAY_SIZE(r8a7790_audio_dmac_channels), | ||
91 | .ts_low_shift = TS_LOW_SHIFT, | ||
92 | .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, | ||
93 | .ts_high_shift = TS_HI_SHIFT, | ||
94 | .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, | ||
95 | .ts_shift = dma_ts_shift, | ||
96 | .ts_shift_num = ARRAY_SIZE(dma_ts_shift), | ||
97 | .dmaor_init = DMAOR_DME, | ||
98 | .chclr_present = 1, | ||
99 | .chclr_bitwise = 1, | ||
100 | }; | ||
101 | |||
102 | static struct resource r8a7790_audio_dmac_resources[] = { | ||
103 | /* Channel registers and DMAOR for low */ | ||
104 | DEFINE_RES_MEM(0xec700020, 0x8663 - 0x20), | ||
105 | DEFINE_RES_IRQ(gic_spi(346)), | ||
106 | DEFINE_RES_NAMED(gic_spi(320), 13, NULL, IORESOURCE_IRQ), | ||
107 | |||
108 | /* Channel registers and DMAOR for hi */ | ||
109 | DEFINE_RES_MEM(0xec720020, 0x8663 - 0x20), /* hi */ | ||
110 | DEFINE_RES_IRQ(gic_spi(347)), | ||
111 | DEFINE_RES_NAMED(gic_spi(333), 13, NULL, IORESOURCE_IRQ), | ||
112 | }; | ||
113 | |||
114 | #define r8a7790_register_audio_dmac(id) \ | ||
115 | platform_device_register_resndata( \ | ||
116 | &platform_bus, "sh-dma-engine", id, \ | ||
117 | &r8a7790_audio_dmac_resources[id * 3], 3, \ | ||
118 | &r8a7790_audio_dmac_platform_data, \ | ||
119 | sizeof(r8a7790_audio_dmac_platform_data)) | ||
120 | |||
33 | static const struct resource pfc_resources[] __initconst = { | 121 | static const struct resource pfc_resources[] __initconst = { |
34 | DEFINE_RES_MEM(0xe6060000, 0x250), | 122 | DEFINE_RES_MEM(0xe6060000, 0x250), |
35 | }; | 123 | }; |
@@ -101,6 +189,8 @@ void __init r8a7790_pinmux_init(void) | |||
101 | r8a7790_register_i2c(1); | 189 | r8a7790_register_i2c(1); |
102 | r8a7790_register_i2c(2); | 190 | r8a7790_register_i2c(2); |
103 | r8a7790_register_i2c(3); | 191 | r8a7790_register_i2c(3); |
192 | r8a7790_register_audio_dmac(0); | ||
193 | r8a7790_register_audio_dmac(1); | ||
104 | } | 194 | } |
105 | 195 | ||
106 | #define __R8A7790_SCIF(scif_type, _scscr, index, baseaddr, irq) \ | 196 | #define __R8A7790_SCIF(scif_type, _scscr, index, baseaddr, irq) \ |
diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig index d2c13ba1190b..abf9ee9bbc3f 100644 --- a/arch/arm/mach-sti/Kconfig +++ b/arch/arm/mach-sti/Kconfig | |||
@@ -5,6 +5,7 @@ menuconfig ARCH_STI | |||
5 | select PINCTRL | 5 | select PINCTRL |
6 | select PINCTRL_ST | 6 | select PINCTRL_ST |
7 | select MFD_SYSCON | 7 | select MFD_SYSCON |
8 | select ARCH_HAS_RESET_CONTROLLER | ||
8 | select HAVE_ARM_SCU if SMP | 9 | select HAVE_ARM_SCU if SMP |
9 | select ARCH_REQUIRE_GPIOLIB | 10 | select ARCH_REQUIRE_GPIOLIB |
10 | select ARM_ERRATA_754322 | 11 | select ARM_ERRATA_754322 |
@@ -24,6 +25,7 @@ if ARCH_STI | |||
24 | config SOC_STIH415 | 25 | config SOC_STIH415 |
25 | bool "STiH415 STMicroelectronics Consumer Electronics family" | 26 | bool "STiH415 STMicroelectronics Consumer Electronics family" |
26 | default y | 27 | default y |
28 | select STIH415_RESET | ||
27 | help | 29 | help |
28 | This enables support for STMicroelectronics Digital Consumer | 30 | This enables support for STMicroelectronics Digital Consumer |
29 | Electronics family StiH415 parts, primarily targeted at set-top-box | 31 | Electronics family StiH415 parts, primarily targeted at set-top-box |
@@ -33,6 +35,7 @@ config SOC_STIH415 | |||
33 | config SOC_STIH416 | 35 | config SOC_STIH416 |
34 | bool "STiH416 STMicroelectronics Consumer Electronics family" | 36 | bool "STiH416 STMicroelectronics Consumer Electronics family" |
35 | default y | 37 | default y |
38 | select STIH416_RESET | ||
36 | help | 39 | help |
37 | This enables support for STMicroelectronics Digital Consumer | 40 | This enables support for STMicroelectronics Digital Consumer |
38 | Electronics family StiH416 parts, primarily targeted at set-top-box | 41 | Electronics family StiH416 parts, primarily targeted at set-top-box |
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index a335126ae18f..f2c89fb8fca9 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -108,7 +108,7 @@ void __init versatile_init_irq(void) | |||
108 | 108 | ||
109 | np = of_find_matching_node_by_address(NULL, vic_of_match, | 109 | np = of_find_matching_node_by_address(NULL, vic_of_match, |
110 | VERSATILE_VIC_BASE); | 110 | VERSATILE_VIC_BASE); |
111 | __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np); | 111 | __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np); |
112 | 112 | ||
113 | writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); | 113 | writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); |
114 | 114 | ||
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 830ff07f3385..3ec6e8e8d368 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c | |||
@@ -595,14 +595,16 @@ void __init orion_spi_1_init(unsigned long mapbase) | |||
595 | /***************************************************************************** | 595 | /***************************************************************************** |
596 | * Watchdog | 596 | * Watchdog |
597 | ****************************************************************************/ | 597 | ****************************************************************************/ |
598 | static struct resource orion_wdt_resource = | 598 | static struct resource orion_wdt_resource[] = { |
599 | DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x28); | 599 | DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04), |
600 | DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04), | ||
601 | }; | ||
600 | 602 | ||
601 | static struct platform_device orion_wdt_device = { | 603 | static struct platform_device orion_wdt_device = { |
602 | .name = "orion_wdt", | 604 | .name = "orion_wdt", |
603 | .id = -1, | 605 | .id = -1, |
604 | .num_resources = 1, | 606 | .num_resources = ARRAY_SIZE(orion_wdt_resource), |
605 | .resource = &orion_wdt_resource, | 607 | .resource = orion_wdt_resource, |
606 | }; | 608 | }; |
607 | 609 | ||
608 | void __init orion_wdt_init(void) | 610 | void __init orion_wdt_init(void) |
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index 1f44e56cc65d..558a239954e8 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c | |||
@@ -256,8 +256,6 @@ static int tegra_ahb_probe(struct platform_device *pdev) | |||
256 | return -ENOMEM; | 256 | return -ENOMEM; |
257 | 257 | ||
258 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 258 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
259 | if (!res) | ||
260 | return -ENODEV; | ||
261 | ahb->regs = devm_ioremap_resource(&pdev->dev, res); | 259 | ahb->regs = devm_ioremap_resource(&pdev->dev, res); |
262 | if (IS_ERR(ahb->regs)) | 260 | if (IS_ERR(ahb->regs)) |
263 | return PTR_ERR(ahb->regs); | 261 | return PTR_ERR(ahb->regs); |
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 962fd35cbd8d..5a86da97a70b 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #define DRIVER_NAME "CCI-400" | 32 | #define DRIVER_NAME "CCI-400" |
33 | #define DRIVER_NAME_PMU DRIVER_NAME " PMU" | 33 | #define DRIVER_NAME_PMU DRIVER_NAME " PMU" |
34 | #define PMU_NAME "CCI_400" | ||
35 | 34 | ||
36 | #define CCI_PORT_CTRL 0x0 | 35 | #define CCI_PORT_CTRL 0x0 |
37 | #define CCI_CTRL_STATUS 0xc | 36 | #define CCI_CTRL_STATUS 0xc |
@@ -88,8 +87,7 @@ static unsigned long cci_ctrl_phys; | |||
88 | 87 | ||
89 | #define CCI_REV_R0 0 | 88 | #define CCI_REV_R0 0 |
90 | #define CCI_REV_R1 1 | 89 | #define CCI_REV_R1 1 |
91 | #define CCI_REV_R0_P4 4 | 90 | #define CCI_REV_R1_PX 5 |
92 | #define CCI_REV_R1_P2 6 | ||
93 | 91 | ||
94 | #define CCI_PMU_EVT_SEL 0x000 | 92 | #define CCI_PMU_EVT_SEL 0x000 |
95 | #define CCI_PMU_CNTR 0x004 | 93 | #define CCI_PMU_CNTR 0x004 |
@@ -163,6 +161,15 @@ static struct pmu_port_event_ranges port_event_range[] = { | |||
163 | }, | 161 | }, |
164 | }; | 162 | }; |
165 | 163 | ||
164 | /* | ||
165 | * Export different PMU names for the different revisions so userspace knows | ||
166 | * because the event ids are different | ||
167 | */ | ||
168 | static char *const pmu_names[] = { | ||
169 | [CCI_REV_R0] = "CCI_400", | ||
170 | [CCI_REV_R1] = "CCI_400_r1", | ||
171 | }; | ||
172 | |||
166 | struct cci_pmu_drv_data { | 173 | struct cci_pmu_drv_data { |
167 | void __iomem *base; | 174 | void __iomem *base; |
168 | struct arm_pmu *cci_pmu; | 175 | struct arm_pmu *cci_pmu; |
@@ -193,21 +200,16 @@ static int probe_cci_revision(void) | |||
193 | rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK; | 200 | rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK; |
194 | rev >>= CCI_PID2_REV_SHIFT; | 201 | rev >>= CCI_PID2_REV_SHIFT; |
195 | 202 | ||
196 | if (rev <= CCI_REV_R0_P4) | 203 | if (rev < CCI_REV_R1_PX) |
197 | return CCI_REV_R0; | 204 | return CCI_REV_R0; |
198 | else if (rev <= CCI_REV_R1_P2) | 205 | else |
199 | return CCI_REV_R1; | 206 | return CCI_REV_R1; |
200 | |||
201 | return -ENOENT; | ||
202 | } | 207 | } |
203 | 208 | ||
204 | static struct pmu_port_event_ranges *port_range_by_rev(void) | 209 | static struct pmu_port_event_ranges *port_range_by_rev(void) |
205 | { | 210 | { |
206 | int rev = probe_cci_revision(); | 211 | int rev = probe_cci_revision(); |
207 | 212 | ||
208 | if (rev < 0) | ||
209 | return NULL; | ||
210 | |||
211 | return &port_event_range[rev]; | 213 | return &port_event_range[rev]; |
212 | } | 214 | } |
213 | 215 | ||
@@ -526,7 +528,7 @@ static void pmu_write_counter(struct perf_event *event, u32 value) | |||
526 | static int cci_pmu_init(struct arm_pmu *cci_pmu, struct platform_device *pdev) | 528 | static int cci_pmu_init(struct arm_pmu *cci_pmu, struct platform_device *pdev) |
527 | { | 529 | { |
528 | *cci_pmu = (struct arm_pmu){ | 530 | *cci_pmu = (struct arm_pmu){ |
529 | .name = PMU_NAME, | 531 | .name = pmu_names[probe_cci_revision()], |
530 | .max_period = (1LLU << 32) - 1, | 532 | .max_period = (1LLU << 32) - 1, |
531 | .get_hw_events = pmu_get_hw_events, | 533 | .get_hw_events = pmu_get_hw_events, |
532 | .get_event_idx = pmu_get_event_idx, | 534 | .get_event_idx = pmu_get_event_idx, |
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 2ac754e18bcf..293e2e0a0a87 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -890,13 +890,12 @@ int __init mvebu_mbus_dt_init(void) | |||
890 | const __be32 *prop; | 890 | const __be32 *prop; |
891 | int ret; | 891 | int ret; |
892 | 892 | ||
893 | np = of_find_matching_node(NULL, of_mvebu_mbus_ids); | 893 | np = of_find_matching_node_and_match(NULL, of_mvebu_mbus_ids, &of_id); |
894 | if (!np) { | 894 | if (!np) { |
895 | pr_err("could not find a matching SoC family\n"); | 895 | pr_err("could not find a matching SoC family\n"); |
896 | return -ENODEV; | 896 | return -ENODEV; |
897 | } | 897 | } |
898 | 898 | ||
899 | of_id = of_match_node(of_mvebu_mbus_ids, np); | ||
900 | mbus_state.soc = of_id->data; | 899 | mbus_state.soc = of_id->data; |
901 | 900 | ||
902 | prop = of_get_property(np, "controller", NULL); | 901 | prop = of_get_property(np, "controller", NULL); |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 2f2b08457c67..244759bbd7b7 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -342,11 +342,11 @@ config HW_RANDOM_TPM | |||
342 | If unsure, say Y. | 342 | If unsure, say Y. |
343 | 343 | ||
344 | config HW_RANDOM_MSM | 344 | config HW_RANDOM_MSM |
345 | tristate "Qualcomm MSM Random Number Generator support" | 345 | tristate "Qualcomm SoCs Random Number Generator support" |
346 | depends on HW_RANDOM && ARCH_MSM | 346 | depends on HW_RANDOM && ARCH_QCOM |
347 | ---help--- | 347 | ---help--- |
348 | This driver provides kernel-side support for the Random Number | 348 | This driver provides kernel-side support for the Random Number |
349 | Generator hardware found on Qualcomm MSM SoCs. | 349 | Generator hardware found on Qualcomm SoCs. |
350 | 350 | ||
351 | To compile this driver as a module, choose M here. the | 351 | To compile this driver as a module, choose M here. the |
352 | module will be called msm-rng. | 352 | module will be called msm-rng. |
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7641965d208d..f9f605695e40 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -111,4 +111,5 @@ source "drivers/clk/qcom/Kconfig" | |||
111 | 111 | ||
112 | endmenu | 112 | endmenu |
113 | 113 | ||
114 | source "drivers/clk/bcm/Kconfig" | ||
114 | source "drivers/clk/mvebu/Kconfig" | 115 | source "drivers/clk/mvebu/Kconfig" |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index a367a9831717..88af4a399d6c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -29,6 +29,7 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o | |||
29 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | 29 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o |
30 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o | 30 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o |
31 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ | 31 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ |
32 | obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/ | ||
32 | obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ | 33 | obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ |
33 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ | 34 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ |
34 | ifeq ($(CONFIG_COMMON_CLK), y) | 35 | ifeq ($(CONFIG_COMMON_CLK), y) |
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig new file mode 100644 index 000000000000..a7262fb8ce55 --- /dev/null +++ b/drivers/clk/bcm/Kconfig | |||
@@ -0,0 +1,9 @@ | |||
1 | config CLK_BCM_KONA | ||
2 | bool "Broadcom Kona CCU clock support" | ||
3 | depends on ARCH_BCM_MOBILE | ||
4 | depends on COMMON_CLK | ||
5 | default y | ||
6 | help | ||
7 | Enable common clock framework support for Broadcom SoCs | ||
8 | using "Kona" style clock control units, including those | ||
9 | in the BCM281xx family. | ||
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile new file mode 100644 index 000000000000..cf93359aa862 --- /dev/null +++ b/drivers/clk/bcm/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o | ||
2 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o | ||
3 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o | ||
diff --git a/drivers/clk/bcm/clk-bcm281xx.c b/drivers/clk/bcm/clk-bcm281xx.c new file mode 100644 index 000000000000..3c66de696aeb --- /dev/null +++ b/drivers/clk/bcm/clk-bcm281xx.c | |||
@@ -0,0 +1,416 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * Copyright 2013 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation version 2. | ||
8 | * | ||
9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
10 | * kind, whether express or implied; without even the implied warranty | ||
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include "clk-kona.h" | ||
16 | #include "dt-bindings/clock/bcm281xx.h" | ||
17 | |||
18 | /* bcm11351 CCU device tree "compatible" strings */ | ||
19 | #define BCM11351_DT_ROOT_CCU_COMPAT "brcm,bcm11351-root-ccu" | ||
20 | #define BCM11351_DT_AON_CCU_COMPAT "brcm,bcm11351-aon-ccu" | ||
21 | #define BCM11351_DT_HUB_CCU_COMPAT "brcm,bcm11351-hub-ccu" | ||
22 | #define BCM11351_DT_MASTER_CCU_COMPAT "brcm,bcm11351-master-ccu" | ||
23 | #define BCM11351_DT_SLAVE_CCU_COMPAT "brcm,bcm11351-slave-ccu" | ||
24 | |||
25 | /* Root CCU clocks */ | ||
26 | |||
27 | static struct peri_clk_data frac_1m_data = { | ||
28 | .gate = HW_SW_GATE(0x214, 16, 0, 1), | ||
29 | .trig = TRIGGER(0x0e04, 0), | ||
30 | .div = FRAC_DIVIDER(0x0e00, 0, 22, 16), | ||
31 | .clocks = CLOCKS("ref_crystal"), | ||
32 | }; | ||
33 | |||
34 | /* AON CCU clocks */ | ||
35 | |||
36 | static struct peri_clk_data hub_timer_data = { | ||
37 | .gate = HW_SW_GATE(0x0414, 16, 0, 1), | ||
38 | .clocks = CLOCKS("bbl_32k", | ||
39 | "frac_1m", | ||
40 | "dft_19_5m"), | ||
41 | .sel = SELECTOR(0x0a10, 0, 2), | ||
42 | .trig = TRIGGER(0x0a40, 4), | ||
43 | }; | ||
44 | |||
45 | static struct peri_clk_data pmu_bsc_data = { | ||
46 | .gate = HW_SW_GATE(0x0418, 16, 0, 1), | ||
47 | .clocks = CLOCKS("ref_crystal", | ||
48 | "pmu_bsc_var", | ||
49 | "bbl_32k"), | ||
50 | .sel = SELECTOR(0x0a04, 0, 2), | ||
51 | .div = DIVIDER(0x0a04, 3, 4), | ||
52 | .trig = TRIGGER(0x0a40, 0), | ||
53 | }; | ||
54 | |||
55 | static struct peri_clk_data pmu_bsc_var_data = { | ||
56 | .clocks = CLOCKS("var_312m", | ||
57 | "ref_312m"), | ||
58 | .sel = SELECTOR(0x0a00, 0, 2), | ||
59 | .div = DIVIDER(0x0a00, 4, 5), | ||
60 | .trig = TRIGGER(0x0a40, 2), | ||
61 | }; | ||
62 | |||
63 | /* Hub CCU clocks */ | ||
64 | |||
65 | static struct peri_clk_data tmon_1m_data = { | ||
66 | .gate = HW_SW_GATE(0x04a4, 18, 2, 3), | ||
67 | .clocks = CLOCKS("ref_crystal", | ||
68 | "frac_1m"), | ||
69 | .sel = SELECTOR(0x0e74, 0, 2), | ||
70 | .trig = TRIGGER(0x0e84, 1), | ||
71 | }; | ||
72 | |||
73 | /* Master CCU clocks */ | ||
74 | |||
75 | static struct peri_clk_data sdio1_data = { | ||
76 | .gate = HW_SW_GATE(0x0358, 18, 2, 3), | ||
77 | .clocks = CLOCKS("ref_crystal", | ||
78 | "var_52m", | ||
79 | "ref_52m", | ||
80 | "var_96m", | ||
81 | "ref_96m"), | ||
82 | .sel = SELECTOR(0x0a28, 0, 3), | ||
83 | .div = DIVIDER(0x0a28, 4, 14), | ||
84 | .trig = TRIGGER(0x0afc, 9), | ||
85 | }; | ||
86 | |||
87 | static struct peri_clk_data sdio2_data = { | ||
88 | .gate = HW_SW_GATE(0x035c, 18, 2, 3), | ||
89 | .clocks = CLOCKS("ref_crystal", | ||
90 | "var_52m", | ||
91 | "ref_52m", | ||
92 | "var_96m", | ||
93 | "ref_96m"), | ||
94 | .sel = SELECTOR(0x0a2c, 0, 3), | ||
95 | .div = DIVIDER(0x0a2c, 4, 14), | ||
96 | .trig = TRIGGER(0x0afc, 10), | ||
97 | }; | ||
98 | |||
99 | static struct peri_clk_data sdio3_data = { | ||
100 | .gate = HW_SW_GATE(0x0364, 18, 2, 3), | ||
101 | .clocks = CLOCKS("ref_crystal", | ||
102 | "var_52m", | ||
103 | "ref_52m", | ||
104 | "var_96m", | ||
105 | "ref_96m"), | ||
106 | .sel = SELECTOR(0x0a34, 0, 3), | ||
107 | .div = DIVIDER(0x0a34, 4, 14), | ||
108 | .trig = TRIGGER(0x0afc, 12), | ||
109 | }; | ||
110 | |||
111 | static struct peri_clk_data sdio4_data = { | ||
112 | .gate = HW_SW_GATE(0x0360, 18, 2, 3), | ||
113 | .clocks = CLOCKS("ref_crystal", | ||
114 | "var_52m", | ||
115 | "ref_52m", | ||
116 | "var_96m", | ||
117 | "ref_96m"), | ||
118 | .sel = SELECTOR(0x0a30, 0, 3), | ||
119 | .div = DIVIDER(0x0a30, 4, 14), | ||
120 | .trig = TRIGGER(0x0afc, 11), | ||
121 | }; | ||
122 | |||
123 | static struct peri_clk_data usb_ic_data = { | ||
124 | .gate = HW_SW_GATE(0x0354, 18, 2, 3), | ||
125 | .clocks = CLOCKS("ref_crystal", | ||
126 | "var_96m", | ||
127 | "ref_96m"), | ||
128 | .div = FIXED_DIVIDER(2), | ||
129 | .sel = SELECTOR(0x0a24, 0, 2), | ||
130 | .trig = TRIGGER(0x0afc, 7), | ||
131 | }; | ||
132 | |||
133 | /* also called usbh_48m */ | ||
134 | static struct peri_clk_data hsic2_48m_data = { | ||
135 | .gate = HW_SW_GATE(0x0370, 18, 2, 3), | ||
136 | .clocks = CLOCKS("ref_crystal", | ||
137 | "var_96m", | ||
138 | "ref_96m"), | ||
139 | .sel = SELECTOR(0x0a38, 0, 2), | ||
140 | .div = FIXED_DIVIDER(2), | ||
141 | .trig = TRIGGER(0x0afc, 5), | ||
142 | }; | ||
143 | |||
144 | /* also called usbh_12m */ | ||
145 | static struct peri_clk_data hsic2_12m_data = { | ||
146 | .gate = HW_SW_GATE(0x0370, 20, 4, 5), | ||
147 | .div = DIVIDER(0x0a38, 12, 2), | ||
148 | .clocks = CLOCKS("ref_crystal", | ||
149 | "var_96m", | ||
150 | "ref_96m"), | ||
151 | .pre_div = FIXED_DIVIDER(2), | ||
152 | .sel = SELECTOR(0x0a38, 0, 2), | ||
153 | .trig = TRIGGER(0x0afc, 5), | ||
154 | }; | ||
155 | |||
156 | /* Slave CCU clocks */ | ||
157 | |||
158 | static struct peri_clk_data uartb_data = { | ||
159 | .gate = HW_SW_GATE(0x0400, 18, 2, 3), | ||
160 | .clocks = CLOCKS("ref_crystal", | ||
161 | "var_156m", | ||
162 | "ref_156m"), | ||
163 | .sel = SELECTOR(0x0a10, 0, 2), | ||
164 | .div = FRAC_DIVIDER(0x0a10, 4, 12, 8), | ||
165 | .trig = TRIGGER(0x0afc, 2), | ||
166 | }; | ||
167 | |||
168 | static struct peri_clk_data uartb2_data = { | ||
169 | .gate = HW_SW_GATE(0x0404, 18, 2, 3), | ||
170 | .clocks = CLOCKS("ref_crystal", | ||
171 | "var_156m", | ||
172 | "ref_156m"), | ||
173 | .sel = SELECTOR(0x0a14, 0, 2), | ||
174 | .div = FRAC_DIVIDER(0x0a14, 4, 12, 8), | ||
175 | .trig = TRIGGER(0x0afc, 3), | ||
176 | }; | ||
177 | |||
178 | static struct peri_clk_data uartb3_data = { | ||
179 | .gate = HW_SW_GATE(0x0408, 18, 2, 3), | ||
180 | .clocks = CLOCKS("ref_crystal", | ||
181 | "var_156m", | ||
182 | "ref_156m"), | ||
183 | .sel = SELECTOR(0x0a18, 0, 2), | ||
184 | .div = FRAC_DIVIDER(0x0a18, 4, 12, 8), | ||
185 | .trig = TRIGGER(0x0afc, 4), | ||
186 | }; | ||
187 | |||
188 | static struct peri_clk_data uartb4_data = { | ||
189 | .gate = HW_SW_GATE(0x0408, 18, 2, 3), | ||
190 | .clocks = CLOCKS("ref_crystal", | ||
191 | "var_156m", | ||
192 | "ref_156m"), | ||
193 | .sel = SELECTOR(0x0a1c, 0, 2), | ||
194 | .div = FRAC_DIVIDER(0x0a1c, 4, 12, 8), | ||
195 | .trig = TRIGGER(0x0afc, 5), | ||
196 | }; | ||
197 | |||
198 | static struct peri_clk_data ssp0_data = { | ||
199 | .gate = HW_SW_GATE(0x0410, 18, 2, 3), | ||
200 | .clocks = CLOCKS("ref_crystal", | ||
201 | "var_104m", | ||
202 | "ref_104m", | ||
203 | "var_96m", | ||
204 | "ref_96m"), | ||
205 | .sel = SELECTOR(0x0a20, 0, 3), | ||
206 | .div = DIVIDER(0x0a20, 4, 14), | ||
207 | .trig = TRIGGER(0x0afc, 6), | ||
208 | }; | ||
209 | |||
210 | static struct peri_clk_data ssp2_data = { | ||
211 | .gate = HW_SW_GATE(0x0418, 18, 2, 3), | ||
212 | .clocks = CLOCKS("ref_crystal", | ||
213 | "var_104m", | ||
214 | "ref_104m", | ||
215 | "var_96m", | ||
216 | "ref_96m"), | ||
217 | .sel = SELECTOR(0x0a28, 0, 3), | ||
218 | .div = DIVIDER(0x0a28, 4, 14), | ||
219 | .trig = TRIGGER(0x0afc, 8), | ||
220 | }; | ||
221 | |||
222 | static struct peri_clk_data bsc1_data = { | ||
223 | .gate = HW_SW_GATE(0x0458, 18, 2, 3), | ||
224 | .clocks = CLOCKS("ref_crystal", | ||
225 | "var_104m", | ||
226 | "ref_104m", | ||
227 | "var_13m", | ||
228 | "ref_13m"), | ||
229 | .sel = SELECTOR(0x0a64, 0, 3), | ||
230 | .trig = TRIGGER(0x0afc, 23), | ||
231 | }; | ||
232 | |||
233 | static struct peri_clk_data bsc2_data = { | ||
234 | .gate = HW_SW_GATE(0x045c, 18, 2, 3), | ||
235 | .clocks = CLOCKS("ref_crystal", | ||
236 | "var_104m", | ||
237 | "ref_104m", | ||
238 | "var_13m", | ||
239 | "ref_13m"), | ||
240 | .sel = SELECTOR(0x0a68, 0, 3), | ||
241 | .trig = TRIGGER(0x0afc, 24), | ||
242 | }; | ||
243 | |||
244 | static struct peri_clk_data bsc3_data = { | ||
245 | .gate = HW_SW_GATE(0x0484, 18, 2, 3), | ||
246 | .clocks = CLOCKS("ref_crystal", | ||
247 | "var_104m", | ||
248 | "ref_104m", | ||
249 | "var_13m", | ||
250 | "ref_13m"), | ||
251 | .sel = SELECTOR(0x0a84, 0, 3), | ||
252 | .trig = TRIGGER(0x0b00, 2), | ||
253 | }; | ||
254 | |||
255 | static struct peri_clk_data pwm_data = { | ||
256 | .gate = HW_SW_GATE(0x0468, 18, 2, 3), | ||
257 | .clocks = CLOCKS("ref_crystal", | ||
258 | "var_104m"), | ||
259 | .sel = SELECTOR(0x0a70, 0, 2), | ||
260 | .div = DIVIDER(0x0a70, 4, 3), | ||
261 | .trig = TRIGGER(0x0afc, 15), | ||
262 | }; | ||
263 | |||
264 | /* | ||
265 | * CCU setup routines | ||
266 | * | ||
267 | * These are called from kona_dt_ccu_setup() to initialize the array | ||
268 | * of clocks provided by the CCU. Once allocated, the entries in | ||
269 | * the array are initialized by calling kona_clk_setup() with the | ||
270 | * initialization data for each clock. They return 0 if successful | ||
271 | * or an error code otherwise. | ||
272 | */ | ||
273 | static int __init bcm281xx_root_ccu_clks_setup(struct ccu_data *ccu) | ||
274 | { | ||
275 | struct clk **clks; | ||
276 | size_t count = BCM281XX_ROOT_CCU_CLOCK_COUNT; | ||
277 | |||
278 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
279 | if (!clks) { | ||
280 | pr_err("%s: failed to allocate root clocks\n", __func__); | ||
281 | return -ENOMEM; | ||
282 | } | ||
283 | ccu->data.clks = clks; | ||
284 | ccu->data.clk_num = count; | ||
285 | |||
286 | PERI_CLK_SETUP(clks, ccu, BCM281XX_ROOT_CCU_FRAC_1M, frac_1m); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int __init bcm281xx_aon_ccu_clks_setup(struct ccu_data *ccu) | ||
292 | { | ||
293 | struct clk **clks; | ||
294 | size_t count = BCM281XX_AON_CCU_CLOCK_COUNT; | ||
295 | |||
296 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
297 | if (!clks) { | ||
298 | pr_err("%s: failed to allocate aon clocks\n", __func__); | ||
299 | return -ENOMEM; | ||
300 | } | ||
301 | ccu->data.clks = clks; | ||
302 | ccu->data.clk_num = count; | ||
303 | |||
304 | PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_HUB_TIMER, hub_timer); | ||
305 | PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC, pmu_bsc); | ||
306 | PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC_VAR, pmu_bsc_var); | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int __init bcm281xx_hub_ccu_clks_setup(struct ccu_data *ccu) | ||
312 | { | ||
313 | struct clk **clks; | ||
314 | size_t count = BCM281XX_HUB_CCU_CLOCK_COUNT; | ||
315 | |||
316 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
317 | if (!clks) { | ||
318 | pr_err("%s: failed to allocate hub clocks\n", __func__); | ||
319 | return -ENOMEM; | ||
320 | } | ||
321 | ccu->data.clks = clks; | ||
322 | ccu->data.clk_num = count; | ||
323 | |||
324 | PERI_CLK_SETUP(clks, ccu, BCM281XX_HUB_CCU_TMON_1M, tmon_1m); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int __init bcm281xx_master_ccu_clks_setup(struct ccu_data *ccu) | ||
330 | { | ||
331 | struct clk **clks; | ||
332 | size_t count = BCM281XX_MASTER_CCU_CLOCK_COUNT; | ||
333 | |||
334 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
335 | if (!clks) { | ||
336 | pr_err("%s: failed to allocate master clocks\n", __func__); | ||
337 | return -ENOMEM; | ||
338 | } | ||
339 | ccu->data.clks = clks; | ||
340 | ccu->data.clk_num = count; | ||
341 | |||
342 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO1, sdio1); | ||
343 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO2, sdio2); | ||
344 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO3, sdio3); | ||
345 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO4, sdio4); | ||
346 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_USB_IC, usb_ic); | ||
347 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_48M, hsic2_48m); | ||
348 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_12M, hsic2_12m); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int __init bcm281xx_slave_ccu_clks_setup(struct ccu_data *ccu) | ||
354 | { | ||
355 | struct clk **clks; | ||
356 | size_t count = BCM281XX_SLAVE_CCU_CLOCK_COUNT; | ||
357 | |||
358 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
359 | if (!clks) { | ||
360 | pr_err("%s: failed to allocate slave clocks\n", __func__); | ||
361 | return -ENOMEM; | ||
362 | } | ||
363 | ccu->data.clks = clks; | ||
364 | ccu->data.clk_num = count; | ||
365 | |||
366 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB, uartb); | ||
367 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB2, uartb2); | ||
368 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB3, uartb3); | ||
369 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB4, uartb4); | ||
370 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP0, ssp0); | ||
371 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP2, ssp2); | ||
372 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC1, bsc1); | ||
373 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC2, bsc2); | ||
374 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC3, bsc3); | ||
375 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_PWM, pwm); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | /* Device tree match table callback functions */ | ||
381 | |||
382 | static void __init kona_dt_root_ccu_setup(struct device_node *node) | ||
383 | { | ||
384 | kona_dt_ccu_setup(node, bcm281xx_root_ccu_clks_setup); | ||
385 | } | ||
386 | |||
387 | static void __init kona_dt_aon_ccu_setup(struct device_node *node) | ||
388 | { | ||
389 | kona_dt_ccu_setup(node, bcm281xx_aon_ccu_clks_setup); | ||
390 | } | ||
391 | |||
392 | static void __init kona_dt_hub_ccu_setup(struct device_node *node) | ||
393 | { | ||
394 | kona_dt_ccu_setup(node, bcm281xx_hub_ccu_clks_setup); | ||
395 | } | ||
396 | |||
397 | static void __init kona_dt_master_ccu_setup(struct device_node *node) | ||
398 | { | ||
399 | kona_dt_ccu_setup(node, bcm281xx_master_ccu_clks_setup); | ||
400 | } | ||
401 | |||
402 | static void __init kona_dt_slave_ccu_setup(struct device_node *node) | ||
403 | { | ||
404 | kona_dt_ccu_setup(node, bcm281xx_slave_ccu_clks_setup); | ||
405 | } | ||
406 | |||
407 | CLK_OF_DECLARE(bcm11351_root_ccu, BCM11351_DT_ROOT_CCU_COMPAT, | ||
408 | kona_dt_root_ccu_setup); | ||
409 | CLK_OF_DECLARE(bcm11351_aon_ccu, BCM11351_DT_AON_CCU_COMPAT, | ||
410 | kona_dt_aon_ccu_setup); | ||
411 | CLK_OF_DECLARE(bcm11351_hub_ccu, BCM11351_DT_HUB_CCU_COMPAT, | ||
412 | kona_dt_hub_ccu_setup); | ||
413 | CLK_OF_DECLARE(bcm11351_master_ccu, BCM11351_DT_MASTER_CCU_COMPAT, | ||
414 | kona_dt_master_ccu_setup); | ||
415 | CLK_OF_DECLARE(bcm11351_slave_ccu, BCM11351_DT_SLAVE_CCU_COMPAT, | ||
416 | kona_dt_slave_ccu_setup); | ||
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c new file mode 100644 index 000000000000..c7607feb18dd --- /dev/null +++ b/drivers/clk/bcm/clk-kona-setup.c | |||
@@ -0,0 +1,769 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * Copyright 2013 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation version 2. | ||
8 | * | ||
9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
10 | * kind, whether express or implied; without even the implied warranty | ||
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/io.h> | ||
16 | #include <linux/of_address.h> | ||
17 | |||
18 | #include "clk-kona.h" | ||
19 | |||
20 | /* These are used when a selector or trigger is found to be unneeded */ | ||
21 | #define selector_clear_exists(sel) ((sel)->width = 0) | ||
22 | #define trigger_clear_exists(trig) FLAG_CLEAR(trig, TRIG, EXISTS) | ||
23 | |||
24 | LIST_HEAD(ccu_list); /* The list of set up CCUs */ | ||
25 | |||
26 | /* Validity checking */ | ||
27 | |||
28 | static bool clk_requires_trigger(struct kona_clk *bcm_clk) | ||
29 | { | ||
30 | struct peri_clk_data *peri = bcm_clk->peri; | ||
31 | struct bcm_clk_sel *sel; | ||
32 | struct bcm_clk_div *div; | ||
33 | |||
34 | if (bcm_clk->type != bcm_clk_peri) | ||
35 | return false; | ||
36 | |||
37 | sel = &peri->sel; | ||
38 | if (sel->parent_count && selector_exists(sel)) | ||
39 | return true; | ||
40 | |||
41 | div = &peri->div; | ||
42 | if (!divider_exists(div)) | ||
43 | return false; | ||
44 | |||
45 | /* Fixed dividers don't need triggers */ | ||
46 | if (!divider_is_fixed(div)) | ||
47 | return true; | ||
48 | |||
49 | div = &peri->pre_div; | ||
50 | |||
51 | return divider_exists(div) && !divider_is_fixed(div); | ||
52 | } | ||
53 | |||
54 | static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) | ||
55 | { | ||
56 | struct peri_clk_data *peri; | ||
57 | struct bcm_clk_gate *gate; | ||
58 | struct bcm_clk_div *div; | ||
59 | struct bcm_clk_sel *sel; | ||
60 | struct bcm_clk_trig *trig; | ||
61 | const char *name; | ||
62 | u32 range; | ||
63 | u32 limit; | ||
64 | |||
65 | BUG_ON(bcm_clk->type != bcm_clk_peri); | ||
66 | peri = bcm_clk->peri; | ||
67 | name = bcm_clk->name; | ||
68 | range = bcm_clk->ccu->range; | ||
69 | |||
70 | limit = range - sizeof(u32); | ||
71 | limit = round_down(limit, sizeof(u32)); | ||
72 | |||
73 | gate = &peri->gate; | ||
74 | if (gate_exists(gate)) { | ||
75 | if (gate->offset > limit) { | ||
76 | pr_err("%s: bad gate offset for %s (%u > %u)\n", | ||
77 | __func__, name, gate->offset, limit); | ||
78 | return false; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | div = &peri->div; | ||
83 | if (divider_exists(div)) { | ||
84 | if (div->offset > limit) { | ||
85 | pr_err("%s: bad divider offset for %s (%u > %u)\n", | ||
86 | __func__, name, div->offset, limit); | ||
87 | return false; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | div = &peri->pre_div; | ||
92 | if (divider_exists(div)) { | ||
93 | if (div->offset > limit) { | ||
94 | pr_err("%s: bad pre-divider offset for %s " | ||
95 | "(%u > %u)\n", | ||
96 | __func__, name, div->offset, limit); | ||
97 | return false; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | sel = &peri->sel; | ||
102 | if (selector_exists(sel)) { | ||
103 | if (sel->offset > limit) { | ||
104 | pr_err("%s: bad selector offset for %s (%u > %u)\n", | ||
105 | __func__, name, sel->offset, limit); | ||
106 | return false; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | trig = &peri->trig; | ||
111 | if (trigger_exists(trig)) { | ||
112 | if (trig->offset > limit) { | ||
113 | pr_err("%s: bad trigger offset for %s (%u > %u)\n", | ||
114 | __func__, name, trig->offset, limit); | ||
115 | return false; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | trig = &peri->pre_trig; | ||
120 | if (trigger_exists(trig)) { | ||
121 | if (trig->offset > limit) { | ||
122 | pr_err("%s: bad pre-trigger offset for %s (%u > %u)\n", | ||
123 | __func__, name, trig->offset, limit); | ||
124 | return false; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | return true; | ||
129 | } | ||
130 | |||
131 | /* A bit position must be less than the number of bits in a 32-bit register. */ | ||
132 | static bool bit_posn_valid(u32 bit_posn, const char *field_name, | ||
133 | const char *clock_name) | ||
134 | { | ||
135 | u32 limit = BITS_PER_BYTE * sizeof(u32) - 1; | ||
136 | |||
137 | if (bit_posn > limit) { | ||
138 | pr_err("%s: bad %s bit for %s (%u > %u)\n", __func__, | ||
139 | field_name, clock_name, bit_posn, limit); | ||
140 | return false; | ||
141 | } | ||
142 | return true; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * A bitfield must be at least 1 bit wide. Both the low-order and | ||
147 | * high-order bits must lie within a 32-bit register. We require | ||
148 | * fields to be less than 32 bits wide, mainly because we use | ||
149 | * shifting to produce field masks, and shifting a full word width | ||
150 | * is not well-defined by the C standard. | ||
151 | */ | ||
152 | static bool bitfield_valid(u32 shift, u32 width, const char *field_name, | ||
153 | const char *clock_name) | ||
154 | { | ||
155 | u32 limit = BITS_PER_BYTE * sizeof(u32); | ||
156 | |||
157 | if (!width) { | ||
158 | pr_err("%s: bad %s field width 0 for %s\n", __func__, | ||
159 | field_name, clock_name); | ||
160 | return false; | ||
161 | } | ||
162 | if (shift + width > limit) { | ||
163 | pr_err("%s: bad %s for %s (%u + %u > %u)\n", __func__, | ||
164 | field_name, clock_name, shift, width, limit); | ||
165 | return false; | ||
166 | } | ||
167 | return true; | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * All gates, if defined, have a status bit, and for hardware-only | ||
172 | * gates, that's it. Gates that can be software controlled also | ||
173 | * have an enable bit. And a gate that can be hardware or software | ||
174 | * controlled will have a hardware/software select bit. | ||
175 | */ | ||
176 | static bool gate_valid(struct bcm_clk_gate *gate, const char *field_name, | ||
177 | const char *clock_name) | ||
178 | { | ||
179 | if (!bit_posn_valid(gate->status_bit, "gate status", clock_name)) | ||
180 | return false; | ||
181 | |||
182 | if (gate_is_sw_controllable(gate)) { | ||
183 | if (!bit_posn_valid(gate->en_bit, "gate enable", clock_name)) | ||
184 | return false; | ||
185 | |||
186 | if (gate_is_hw_controllable(gate)) { | ||
187 | if (!bit_posn_valid(gate->hw_sw_sel_bit, | ||
188 | "gate hw/sw select", | ||
189 | clock_name)) | ||
190 | return false; | ||
191 | } | ||
192 | } else { | ||
193 | BUG_ON(!gate_is_hw_controllable(gate)); | ||
194 | } | ||
195 | |||
196 | return true; | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * A selector bitfield must be valid. Its parent_sel array must | ||
201 | * also be reasonable for the field. | ||
202 | */ | ||
203 | static bool sel_valid(struct bcm_clk_sel *sel, const char *field_name, | ||
204 | const char *clock_name) | ||
205 | { | ||
206 | if (!bitfield_valid(sel->shift, sel->width, field_name, clock_name)) | ||
207 | return false; | ||
208 | |||
209 | if (sel->parent_count) { | ||
210 | u32 max_sel; | ||
211 | u32 limit; | ||
212 | |||
213 | /* | ||
214 | * Make sure the selector field can hold all the | ||
215 | * selector values we expect to be able to use. A | ||
216 | * clock only needs to have a selector defined if it | ||
217 | * has more than one parent. And in that case the | ||
218 | * highest selector value will be in the last entry | ||
219 | * in the array. | ||
220 | */ | ||
221 | max_sel = sel->parent_sel[sel->parent_count - 1]; | ||
222 | limit = (1 << sel->width) - 1; | ||
223 | if (max_sel > limit) { | ||
224 | pr_err("%s: bad selector for %s " | ||
225 | "(%u needs > %u bits)\n", | ||
226 | __func__, clock_name, max_sel, | ||
227 | sel->width); | ||
228 | return false; | ||
229 | } | ||
230 | } else { | ||
231 | pr_warn("%s: ignoring selector for %s (no parents)\n", | ||
232 | __func__, clock_name); | ||
233 | selector_clear_exists(sel); | ||
234 | kfree(sel->parent_sel); | ||
235 | sel->parent_sel = NULL; | ||
236 | } | ||
237 | |||
238 | return true; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * A fixed divider just needs to be non-zero. A variable divider | ||
243 | * has to have a valid divider bitfield, and if it has a fraction, | ||
244 | * the width of the fraction must not be no more than the width of | ||
245 | * the divider as a whole. | ||
246 | */ | ||
247 | static bool div_valid(struct bcm_clk_div *div, const char *field_name, | ||
248 | const char *clock_name) | ||
249 | { | ||
250 | if (divider_is_fixed(div)) { | ||
251 | /* Any fixed divider value but 0 is OK */ | ||
252 | if (div->fixed == 0) { | ||
253 | pr_err("%s: bad %s fixed value 0 for %s\n", __func__, | ||
254 | field_name, clock_name); | ||
255 | return false; | ||
256 | } | ||
257 | return true; | ||
258 | } | ||
259 | if (!bitfield_valid(div->shift, div->width, field_name, clock_name)) | ||
260 | return false; | ||
261 | |||
262 | if (divider_has_fraction(div)) | ||
263 | if (div->frac_width > div->width) { | ||
264 | pr_warn("%s: bad %s fraction width for %s (%u > %u)\n", | ||
265 | __func__, field_name, clock_name, | ||
266 | div->frac_width, div->width); | ||
267 | return false; | ||
268 | } | ||
269 | |||
270 | return true; | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * If a clock has two dividers, the combined number of fractional | ||
275 | * bits must be representable in a 32-bit unsigned value. This | ||
276 | * is because we scale up a dividend using both dividers before | ||
277 | * dividing to improve accuracy, and we need to avoid overflow. | ||
278 | */ | ||
279 | static bool kona_dividers_valid(struct kona_clk *bcm_clk) | ||
280 | { | ||
281 | struct peri_clk_data *peri = bcm_clk->peri; | ||
282 | struct bcm_clk_div *div; | ||
283 | struct bcm_clk_div *pre_div; | ||
284 | u32 limit; | ||
285 | |||
286 | BUG_ON(bcm_clk->type != bcm_clk_peri); | ||
287 | |||
288 | if (!divider_exists(&peri->div) || !divider_exists(&peri->pre_div)) | ||
289 | return true; | ||
290 | |||
291 | div = &peri->div; | ||
292 | pre_div = &peri->pre_div; | ||
293 | if (divider_is_fixed(div) || divider_is_fixed(pre_div)) | ||
294 | return true; | ||
295 | |||
296 | limit = BITS_PER_BYTE * sizeof(u32); | ||
297 | |||
298 | return div->frac_width + pre_div->frac_width <= limit; | ||
299 | } | ||
300 | |||
301 | |||
302 | /* A trigger just needs to represent a valid bit position */ | ||
303 | static bool trig_valid(struct bcm_clk_trig *trig, const char *field_name, | ||
304 | const char *clock_name) | ||
305 | { | ||
306 | return bit_posn_valid(trig->bit, field_name, clock_name); | ||
307 | } | ||
308 | |||
309 | /* Determine whether the set of peripheral clock registers are valid. */ | ||
310 | static bool | ||
311 | peri_clk_data_valid(struct kona_clk *bcm_clk) | ||
312 | { | ||
313 | struct peri_clk_data *peri; | ||
314 | struct bcm_clk_gate *gate; | ||
315 | struct bcm_clk_sel *sel; | ||
316 | struct bcm_clk_div *div; | ||
317 | struct bcm_clk_div *pre_div; | ||
318 | struct bcm_clk_trig *trig; | ||
319 | const char *name; | ||
320 | |||
321 | BUG_ON(bcm_clk->type != bcm_clk_peri); | ||
322 | |||
323 | /* | ||
324 | * First validate register offsets. This is the only place | ||
325 | * where we need something from the ccu, so we do these | ||
326 | * together. | ||
327 | */ | ||
328 | if (!peri_clk_data_offsets_valid(bcm_clk)) | ||
329 | return false; | ||
330 | |||
331 | peri = bcm_clk->peri; | ||
332 | name = bcm_clk->name; | ||
333 | gate = &peri->gate; | ||
334 | if (gate_exists(gate) && !gate_valid(gate, "gate", name)) | ||
335 | return false; | ||
336 | |||
337 | sel = &peri->sel; | ||
338 | if (selector_exists(sel)) { | ||
339 | if (!sel_valid(sel, "selector", name)) | ||
340 | return false; | ||
341 | |||
342 | } else if (sel->parent_count > 1) { | ||
343 | pr_err("%s: multiple parents but no selector for %s\n", | ||
344 | __func__, name); | ||
345 | |||
346 | return false; | ||
347 | } | ||
348 | |||
349 | div = &peri->div; | ||
350 | pre_div = &peri->pre_div; | ||
351 | if (divider_exists(div)) { | ||
352 | if (!div_valid(div, "divider", name)) | ||
353 | return false; | ||
354 | |||
355 | if (divider_exists(pre_div)) | ||
356 | if (!div_valid(pre_div, "pre-divider", name)) | ||
357 | return false; | ||
358 | } else if (divider_exists(pre_div)) { | ||
359 | pr_err("%s: pre-divider but no divider for %s\n", __func__, | ||
360 | name); | ||
361 | return false; | ||
362 | } | ||
363 | |||
364 | trig = &peri->trig; | ||
365 | if (trigger_exists(trig)) { | ||
366 | if (!trig_valid(trig, "trigger", name)) | ||
367 | return false; | ||
368 | |||
369 | if (trigger_exists(&peri->pre_trig)) { | ||
370 | if (!trig_valid(trig, "pre-trigger", name)) { | ||
371 | return false; | ||
372 | } | ||
373 | } | ||
374 | if (!clk_requires_trigger(bcm_clk)) { | ||
375 | pr_warn("%s: ignoring trigger for %s (not needed)\n", | ||
376 | __func__, name); | ||
377 | trigger_clear_exists(trig); | ||
378 | } | ||
379 | } else if (trigger_exists(&peri->pre_trig)) { | ||
380 | pr_err("%s: pre-trigger but no trigger for %s\n", __func__, | ||
381 | name); | ||
382 | return false; | ||
383 | } else if (clk_requires_trigger(bcm_clk)) { | ||
384 | pr_err("%s: required trigger missing for %s\n", __func__, | ||
385 | name); | ||
386 | return false; | ||
387 | } | ||
388 | |||
389 | return kona_dividers_valid(bcm_clk); | ||
390 | } | ||
391 | |||
392 | static bool kona_clk_valid(struct kona_clk *bcm_clk) | ||
393 | { | ||
394 | switch (bcm_clk->type) { | ||
395 | case bcm_clk_peri: | ||
396 | if (!peri_clk_data_valid(bcm_clk)) | ||
397 | return false; | ||
398 | break; | ||
399 | default: | ||
400 | pr_err("%s: unrecognized clock type (%d)\n", __func__, | ||
401 | (int)bcm_clk->type); | ||
402 | return false; | ||
403 | } | ||
404 | return true; | ||
405 | } | ||
406 | |||
407 | /* | ||
408 | * Scan an array of parent clock names to determine whether there | ||
409 | * are any entries containing BAD_CLK_NAME. Such entries are | ||
410 | * placeholders for non-supported clocks. Keep track of the | ||
411 | * position of each clock name in the original array. | ||
412 | * | ||
413 | * Allocates an array of pointers to to hold the names of all | ||
414 | * non-null entries in the original array, and returns a pointer to | ||
415 | * that array in *names. This will be used for registering the | ||
416 | * clock with the common clock code. On successful return, | ||
417 | * *count indicates how many entries are in that names array. | ||
418 | * | ||
419 | * If there is more than one entry in the resulting names array, | ||
420 | * another array is allocated to record the parent selector value | ||
421 | * for each (defined) parent clock. This is the value that | ||
422 | * represents this parent clock in the clock's source selector | ||
423 | * register. The position of the clock in the original parent array | ||
424 | * defines that selector value. The number of entries in this array | ||
425 | * is the same as the number of entries in the parent names array. | ||
426 | * | ||
427 | * The array of selector values is returned. If the clock has no | ||
428 | * parents, no selector is required and a null pointer is returned. | ||
429 | * | ||
430 | * Returns a null pointer if the clock names array supplied was | ||
431 | * null. (This is not an error.) | ||
432 | * | ||
433 | * Returns a pointer-coded error if an error occurs. | ||
434 | */ | ||
435 | static u32 *parent_process(const char *clocks[], | ||
436 | u32 *count, const char ***names) | ||
437 | { | ||
438 | static const char **parent_names; | ||
439 | static u32 *parent_sel; | ||
440 | const char **clock; | ||
441 | u32 parent_count; | ||
442 | u32 bad_count = 0; | ||
443 | u32 orig_count; | ||
444 | u32 i; | ||
445 | u32 j; | ||
446 | |||
447 | *count = 0; /* In case of early return */ | ||
448 | *names = NULL; | ||
449 | if (!clocks) | ||
450 | return NULL; | ||
451 | |||
452 | /* | ||
453 | * Count the number of names in the null-terminated array, | ||
454 | * and find out how many of those are actually clock names. | ||
455 | */ | ||
456 | for (clock = clocks; *clock; clock++) | ||
457 | if (*clock == BAD_CLK_NAME) | ||
458 | bad_count++; | ||
459 | orig_count = (u32)(clock - clocks); | ||
460 | parent_count = orig_count - bad_count; | ||
461 | |||
462 | /* If all clocks are unsupported, we treat it as no clock */ | ||
463 | if (!parent_count) | ||
464 | return NULL; | ||
465 | |||
466 | /* Avoid exceeding our parent clock limit */ | ||
467 | if (parent_count > PARENT_COUNT_MAX) { | ||
468 | pr_err("%s: too many parents (%u > %u)\n", __func__, | ||
469 | parent_count, PARENT_COUNT_MAX); | ||
470 | return ERR_PTR(-EINVAL); | ||
471 | } | ||
472 | |||
473 | /* | ||
474 | * There is one parent name for each defined parent clock. | ||
475 | * We also maintain an array containing the selector value | ||
476 | * for each defined clock. If there's only one clock, the | ||
477 | * selector is not required, but we allocate space for the | ||
478 | * array anyway to keep things simple. | ||
479 | */ | ||
480 | parent_names = kmalloc(parent_count * sizeof(parent_names), GFP_KERNEL); | ||
481 | if (!parent_names) { | ||
482 | pr_err("%s: error allocating %u parent names\n", __func__, | ||
483 | parent_count); | ||
484 | return ERR_PTR(-ENOMEM); | ||
485 | } | ||
486 | |||
487 | /* There is at least one parent, so allocate a selector array */ | ||
488 | |||
489 | parent_sel = kmalloc(parent_count * sizeof(*parent_sel), GFP_KERNEL); | ||
490 | if (!parent_sel) { | ||
491 | pr_err("%s: error allocating %u parent selectors\n", __func__, | ||
492 | parent_count); | ||
493 | kfree(parent_names); | ||
494 | |||
495 | return ERR_PTR(-ENOMEM); | ||
496 | } | ||
497 | |||
498 | /* Now fill in the parent names and selector arrays */ | ||
499 | for (i = 0, j = 0; i < orig_count; i++) { | ||
500 | if (clocks[i] != BAD_CLK_NAME) { | ||
501 | parent_names[j] = clocks[i]; | ||
502 | parent_sel[j] = i; | ||
503 | j++; | ||
504 | } | ||
505 | } | ||
506 | *names = parent_names; | ||
507 | *count = parent_count; | ||
508 | |||
509 | return parent_sel; | ||
510 | } | ||
511 | |||
512 | static int | ||
513 | clk_sel_setup(const char **clocks, struct bcm_clk_sel *sel, | ||
514 | struct clk_init_data *init_data) | ||
515 | { | ||
516 | const char **parent_names = NULL; | ||
517 | u32 parent_count = 0; | ||
518 | u32 *parent_sel; | ||
519 | |||
520 | /* | ||
521 | * If a peripheral clock has multiple parents, the value | ||
522 | * used by the hardware to select that parent is represented | ||
523 | * by the parent clock's position in the "clocks" list. Some | ||
524 | * values don't have defined or supported clocks; these will | ||
525 | * have BAD_CLK_NAME entries in the parents[] array. The | ||
526 | * list is terminated by a NULL entry. | ||
527 | * | ||
528 | * We need to supply (only) the names of defined parent | ||
529 | * clocks when registering a clock though, so we use an | ||
530 | * array of parent selector values to map between the | ||
531 | * indexes the common clock code uses and the selector | ||
532 | * values we need. | ||
533 | */ | ||
534 | parent_sel = parent_process(clocks, &parent_count, &parent_names); | ||
535 | if (IS_ERR(parent_sel)) { | ||
536 | int ret = PTR_ERR(parent_sel); | ||
537 | |||
538 | pr_err("%s: error processing parent clocks for %s (%d)\n", | ||
539 | __func__, init_data->name, ret); | ||
540 | |||
541 | return ret; | ||
542 | } | ||
543 | |||
544 | init_data->parent_names = parent_names; | ||
545 | init_data->num_parents = parent_count; | ||
546 | |||
547 | sel->parent_count = parent_count; | ||
548 | sel->parent_sel = parent_sel; | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static void clk_sel_teardown(struct bcm_clk_sel *sel, | ||
554 | struct clk_init_data *init_data) | ||
555 | { | ||
556 | kfree(sel->parent_sel); | ||
557 | sel->parent_sel = NULL; | ||
558 | sel->parent_count = 0; | ||
559 | |||
560 | init_data->num_parents = 0; | ||
561 | kfree(init_data->parent_names); | ||
562 | init_data->parent_names = NULL; | ||
563 | } | ||
564 | |||
565 | static void peri_clk_teardown(struct peri_clk_data *data, | ||
566 | struct clk_init_data *init_data) | ||
567 | { | ||
568 | clk_sel_teardown(&data->sel, init_data); | ||
569 | init_data->ops = NULL; | ||
570 | } | ||
571 | |||
572 | /* | ||
573 | * Caller is responsible for freeing the parent_names[] and | ||
574 | * parent_sel[] arrays in the peripheral clock's "data" structure | ||
575 | * that can be assigned if the clock has one or more parent clocks | ||
576 | * associated with it. | ||
577 | */ | ||
578 | static int peri_clk_setup(struct ccu_data *ccu, struct peri_clk_data *data, | ||
579 | struct clk_init_data *init_data) | ||
580 | { | ||
581 | init_data->ops = &kona_peri_clk_ops; | ||
582 | init_data->flags = CLK_IGNORE_UNUSED; | ||
583 | |||
584 | return clk_sel_setup(data->clocks, &data->sel, init_data); | ||
585 | } | ||
586 | |||
587 | static void bcm_clk_teardown(struct kona_clk *bcm_clk) | ||
588 | { | ||
589 | switch (bcm_clk->type) { | ||
590 | case bcm_clk_peri: | ||
591 | peri_clk_teardown(bcm_clk->data, &bcm_clk->init_data); | ||
592 | break; | ||
593 | default: | ||
594 | break; | ||
595 | } | ||
596 | bcm_clk->data = NULL; | ||
597 | bcm_clk->type = bcm_clk_none; | ||
598 | } | ||
599 | |||
600 | static void kona_clk_teardown(struct clk *clk) | ||
601 | { | ||
602 | struct clk_hw *hw; | ||
603 | struct kona_clk *bcm_clk; | ||
604 | |||
605 | if (!clk) | ||
606 | return; | ||
607 | |||
608 | hw = __clk_get_hw(clk); | ||
609 | if (!hw) { | ||
610 | pr_err("%s: clk %p has null hw pointer\n", __func__, clk); | ||
611 | return; | ||
612 | } | ||
613 | clk_unregister(clk); | ||
614 | |||
615 | bcm_clk = to_kona_clk(hw); | ||
616 | bcm_clk_teardown(bcm_clk); | ||
617 | } | ||
618 | |||
619 | struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | ||
620 | enum bcm_clk_type type, void *data) | ||
621 | { | ||
622 | struct kona_clk *bcm_clk; | ||
623 | struct clk_init_data *init_data; | ||
624 | struct clk *clk = NULL; | ||
625 | |||
626 | bcm_clk = kzalloc(sizeof(*bcm_clk), GFP_KERNEL); | ||
627 | if (!bcm_clk) { | ||
628 | pr_err("%s: failed to allocate bcm_clk for %s\n", __func__, | ||
629 | name); | ||
630 | return NULL; | ||
631 | } | ||
632 | bcm_clk->ccu = ccu; | ||
633 | bcm_clk->name = name; | ||
634 | |||
635 | init_data = &bcm_clk->init_data; | ||
636 | init_data->name = name; | ||
637 | switch (type) { | ||
638 | case bcm_clk_peri: | ||
639 | if (peri_clk_setup(ccu, data, init_data)) | ||
640 | goto out_free; | ||
641 | break; | ||
642 | default: | ||
643 | data = NULL; | ||
644 | break; | ||
645 | } | ||
646 | bcm_clk->type = type; | ||
647 | bcm_clk->data = data; | ||
648 | |||
649 | /* Make sure everything makes sense before we set it up */ | ||
650 | if (!kona_clk_valid(bcm_clk)) { | ||
651 | pr_err("%s: clock data invalid for %s\n", __func__, name); | ||
652 | goto out_teardown; | ||
653 | } | ||
654 | |||
655 | bcm_clk->hw.init = init_data; | ||
656 | clk = clk_register(NULL, &bcm_clk->hw); | ||
657 | if (IS_ERR(clk)) { | ||
658 | pr_err("%s: error registering clock %s (%ld)\n", __func__, | ||
659 | name, PTR_ERR(clk)); | ||
660 | goto out_teardown; | ||
661 | } | ||
662 | BUG_ON(!clk); | ||
663 | |||
664 | return clk; | ||
665 | out_teardown: | ||
666 | bcm_clk_teardown(bcm_clk); | ||
667 | out_free: | ||
668 | kfree(bcm_clk); | ||
669 | |||
670 | return NULL; | ||
671 | } | ||
672 | |||
673 | static void ccu_clks_teardown(struct ccu_data *ccu) | ||
674 | { | ||
675 | u32 i; | ||
676 | |||
677 | for (i = 0; i < ccu->data.clk_num; i++) | ||
678 | kona_clk_teardown(ccu->data.clks[i]); | ||
679 | kfree(ccu->data.clks); | ||
680 | } | ||
681 | |||
682 | static void kona_ccu_teardown(struct ccu_data *ccu) | ||
683 | { | ||
684 | if (!ccu) | ||
685 | return; | ||
686 | |||
687 | if (!ccu->base) | ||
688 | goto done; | ||
689 | |||
690 | of_clk_del_provider(ccu->node); /* safe if never added */ | ||
691 | ccu_clks_teardown(ccu); | ||
692 | list_del(&ccu->links); | ||
693 | of_node_put(ccu->node); | ||
694 | iounmap(ccu->base); | ||
695 | done: | ||
696 | kfree(ccu->name); | ||
697 | kfree(ccu); | ||
698 | } | ||
699 | |||
700 | /* | ||
701 | * Set up a CCU. Call the provided ccu_clks_setup callback to | ||
702 | * initialize the array of clocks provided by the CCU. | ||
703 | */ | ||
704 | void __init kona_dt_ccu_setup(struct device_node *node, | ||
705 | int (*ccu_clks_setup)(struct ccu_data *)) | ||
706 | { | ||
707 | struct ccu_data *ccu; | ||
708 | struct resource res = { 0 }; | ||
709 | resource_size_t range; | ||
710 | int ret; | ||
711 | |||
712 | ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); | ||
713 | if (ccu) | ||
714 | ccu->name = kstrdup(node->name, GFP_KERNEL); | ||
715 | if (!ccu || !ccu->name) { | ||
716 | pr_err("%s: unable to allocate CCU struct for %s\n", | ||
717 | __func__, node->name); | ||
718 | kfree(ccu); | ||
719 | |||
720 | return; | ||
721 | } | ||
722 | |||
723 | ret = of_address_to_resource(node, 0, &res); | ||
724 | if (ret) { | ||
725 | pr_err("%s: no valid CCU registers found for %s\n", __func__, | ||
726 | node->name); | ||
727 | goto out_err; | ||
728 | } | ||
729 | |||
730 | range = resource_size(&res); | ||
731 | if (range > (resource_size_t)U32_MAX) { | ||
732 | pr_err("%s: address range too large for %s\n", __func__, | ||
733 | node->name); | ||
734 | goto out_err; | ||
735 | } | ||
736 | |||
737 | ccu->range = (u32)range; | ||
738 | ccu->base = ioremap(res.start, ccu->range); | ||
739 | if (!ccu->base) { | ||
740 | pr_err("%s: unable to map CCU registers for %s\n", __func__, | ||
741 | node->name); | ||
742 | goto out_err; | ||
743 | } | ||
744 | |||
745 | spin_lock_init(&ccu->lock); | ||
746 | INIT_LIST_HEAD(&ccu->links); | ||
747 | ccu->node = of_node_get(node); | ||
748 | |||
749 | list_add_tail(&ccu->links, &ccu_list); | ||
750 | |||
751 | /* Set up clocks array (in ccu->data) */ | ||
752 | if (ccu_clks_setup(ccu)) | ||
753 | goto out_err; | ||
754 | |||
755 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->data); | ||
756 | if (ret) { | ||
757 | pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, | ||
758 | node->name, ret); | ||
759 | goto out_err; | ||
760 | } | ||
761 | |||
762 | if (!kona_ccu_init(ccu)) | ||
763 | pr_err("Broadcom %s initialization had errors\n", node->name); | ||
764 | |||
765 | return; | ||
766 | out_err: | ||
767 | kona_ccu_teardown(ccu); | ||
768 | pr_err("Broadcom %s setup aborted\n", node->name); | ||
769 | } | ||
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c new file mode 100644 index 000000000000..e3d339e08309 --- /dev/null +++ b/drivers/clk/bcm/clk-kona.c | |||
@@ -0,0 +1,1033 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * Copyright 2013 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation version 2. | ||
8 | * | ||
9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
10 | * kind, whether express or implied; without even the implied warranty | ||
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include "clk-kona.h" | ||
16 | |||
17 | #include <linux/delay.h> | ||
18 | |||
19 | #define CCU_ACCESS_PASSWORD 0xA5A500 | ||
20 | #define CLK_GATE_DELAY_LOOP 2000 | ||
21 | |||
22 | /* Bitfield operations */ | ||
23 | |||
24 | /* Produces a mask of set bits covering a range of a 32-bit value */ | ||
25 | static inline u32 bitfield_mask(u32 shift, u32 width) | ||
26 | { | ||
27 | return ((1 << width) - 1) << shift; | ||
28 | } | ||
29 | |||
30 | /* Extract the value of a bitfield found within a given register value */ | ||
31 | static inline u32 bitfield_extract(u32 reg_val, u32 shift, u32 width) | ||
32 | { | ||
33 | return (reg_val & bitfield_mask(shift, width)) >> shift; | ||
34 | } | ||
35 | |||
36 | /* Replace the value of a bitfield found within a given register value */ | ||
37 | static inline u32 bitfield_replace(u32 reg_val, u32 shift, u32 width, u32 val) | ||
38 | { | ||
39 | u32 mask = bitfield_mask(shift, width); | ||
40 | |||
41 | return (reg_val & ~mask) | (val << shift); | ||
42 | } | ||
43 | |||
44 | /* Divider and scaling helpers */ | ||
45 | |||
46 | /* | ||
47 | * Implement DIV_ROUND_CLOSEST() for 64-bit dividend and both values | ||
48 | * unsigned. Note that unlike do_div(), the remainder is discarded | ||
49 | * and the return value is the quotient (not the remainder). | ||
50 | */ | ||
51 | u64 do_div_round_closest(u64 dividend, unsigned long divisor) | ||
52 | { | ||
53 | u64 result; | ||
54 | |||
55 | result = dividend + ((u64)divisor >> 1); | ||
56 | (void)do_div(result, divisor); | ||
57 | |||
58 | return result; | ||
59 | } | ||
60 | |||
61 | /* Convert a divider into the scaled divisor value it represents. */ | ||
62 | static inline u64 scaled_div_value(struct bcm_clk_div *div, u32 reg_div) | ||
63 | { | ||
64 | return (u64)reg_div + ((u64)1 << div->frac_width); | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * Build a scaled divider value as close as possible to the | ||
69 | * given whole part (div_value) and fractional part (expressed | ||
70 | * in billionths). | ||
71 | */ | ||
72 | u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, u32 billionths) | ||
73 | { | ||
74 | u64 combined; | ||
75 | |||
76 | BUG_ON(!div_value); | ||
77 | BUG_ON(billionths >= BILLION); | ||
78 | |||
79 | combined = (u64)div_value * BILLION + billionths; | ||
80 | combined <<= div->frac_width; | ||
81 | |||
82 | return do_div_round_closest(combined, BILLION); | ||
83 | } | ||
84 | |||
85 | /* The scaled minimum divisor representable by a divider */ | ||
86 | static inline u64 | ||
87 | scaled_div_min(struct bcm_clk_div *div) | ||
88 | { | ||
89 | if (divider_is_fixed(div)) | ||
90 | return (u64)div->fixed; | ||
91 | |||
92 | return scaled_div_value(div, 0); | ||
93 | } | ||
94 | |||
95 | /* The scaled maximum divisor representable by a divider */ | ||
96 | u64 scaled_div_max(struct bcm_clk_div *div) | ||
97 | { | ||
98 | u32 reg_div; | ||
99 | |||
100 | if (divider_is_fixed(div)) | ||
101 | return (u64)div->fixed; | ||
102 | |||
103 | reg_div = ((u32)1 << div->width) - 1; | ||
104 | |||
105 | return scaled_div_value(div, reg_div); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Convert a scaled divisor into its divider representation as | ||
110 | * stored in a divider register field. | ||
111 | */ | ||
112 | static inline u32 | ||
113 | divider(struct bcm_clk_div *div, u64 scaled_div) | ||
114 | { | ||
115 | BUG_ON(scaled_div < scaled_div_min(div)); | ||
116 | BUG_ON(scaled_div > scaled_div_max(div)); | ||
117 | |||
118 | return (u32)(scaled_div - ((u64)1 << div->frac_width)); | ||
119 | } | ||
120 | |||
121 | /* Return a rate scaled for use when dividing by a scaled divisor. */ | ||
122 | static inline u64 | ||
123 | scale_rate(struct bcm_clk_div *div, u32 rate) | ||
124 | { | ||
125 | if (divider_is_fixed(div)) | ||
126 | return (u64)rate; | ||
127 | |||
128 | return (u64)rate << div->frac_width; | ||
129 | } | ||
130 | |||
131 | /* CCU access */ | ||
132 | |||
133 | /* Read a 32-bit register value from a CCU's address space. */ | ||
134 | static inline u32 __ccu_read(struct ccu_data *ccu, u32 reg_offset) | ||
135 | { | ||
136 | return readl(ccu->base + reg_offset); | ||
137 | } | ||
138 | |||
139 | /* Write a 32-bit register value into a CCU's address space. */ | ||
140 | static inline void | ||
141 | __ccu_write(struct ccu_data *ccu, u32 reg_offset, u32 reg_val) | ||
142 | { | ||
143 | writel(reg_val, ccu->base + reg_offset); | ||
144 | } | ||
145 | |||
146 | static inline unsigned long ccu_lock(struct ccu_data *ccu) | ||
147 | { | ||
148 | unsigned long flags; | ||
149 | |||
150 | spin_lock_irqsave(&ccu->lock, flags); | ||
151 | |||
152 | return flags; | ||
153 | } | ||
154 | static inline void ccu_unlock(struct ccu_data *ccu, unsigned long flags) | ||
155 | { | ||
156 | spin_unlock_irqrestore(&ccu->lock, flags); | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Enable/disable write access to CCU protected registers. The | ||
161 | * WR_ACCESS register for all CCUs is at offset 0. | ||
162 | */ | ||
163 | static inline void __ccu_write_enable(struct ccu_data *ccu) | ||
164 | { | ||
165 | if (ccu->write_enabled) { | ||
166 | pr_err("%s: access already enabled for %s\n", __func__, | ||
167 | ccu->name); | ||
168 | return; | ||
169 | } | ||
170 | ccu->write_enabled = true; | ||
171 | __ccu_write(ccu, 0, CCU_ACCESS_PASSWORD | 1); | ||
172 | } | ||
173 | |||
174 | static inline void __ccu_write_disable(struct ccu_data *ccu) | ||
175 | { | ||
176 | if (!ccu->write_enabled) { | ||
177 | pr_err("%s: access wasn't enabled for %s\n", __func__, | ||
178 | ccu->name); | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | __ccu_write(ccu, 0, CCU_ACCESS_PASSWORD); | ||
183 | ccu->write_enabled = false; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Poll a register in a CCU's address space, returning when the | ||
188 | * specified bit in that register's value is set (or clear). Delay | ||
189 | * a microsecond after each read of the register. Returns true if | ||
190 | * successful, or false if we gave up trying. | ||
191 | * | ||
192 | * Caller must ensure the CCU lock is held. | ||
193 | */ | ||
194 | static inline bool | ||
195 | __ccu_wait_bit(struct ccu_data *ccu, u32 reg_offset, u32 bit, bool want) | ||
196 | { | ||
197 | unsigned int tries; | ||
198 | u32 bit_mask = 1 << bit; | ||
199 | |||
200 | for (tries = 0; tries < CLK_GATE_DELAY_LOOP; tries++) { | ||
201 | u32 val; | ||
202 | bool bit_val; | ||
203 | |||
204 | val = __ccu_read(ccu, reg_offset); | ||
205 | bit_val = (val & bit_mask) != 0; | ||
206 | if (bit_val == want) | ||
207 | return true; | ||
208 | udelay(1); | ||
209 | } | ||
210 | return false; | ||
211 | } | ||
212 | |||
213 | /* Gate operations */ | ||
214 | |||
215 | /* Determine whether a clock is gated. CCU lock must be held. */ | ||
216 | static bool | ||
217 | __is_clk_gate_enabled(struct ccu_data *ccu, struct bcm_clk_gate *gate) | ||
218 | { | ||
219 | u32 bit_mask; | ||
220 | u32 reg_val; | ||
221 | |||
222 | /* If there is no gate we can assume it's enabled. */ | ||
223 | if (!gate_exists(gate)) | ||
224 | return true; | ||
225 | |||
226 | bit_mask = 1 << gate->status_bit; | ||
227 | reg_val = __ccu_read(ccu, gate->offset); | ||
228 | |||
229 | return (reg_val & bit_mask) != 0; | ||
230 | } | ||
231 | |||
232 | /* Determine whether a clock is gated. */ | ||
233 | static bool | ||
234 | is_clk_gate_enabled(struct ccu_data *ccu, struct bcm_clk_gate *gate) | ||
235 | { | ||
236 | long flags; | ||
237 | bool ret; | ||
238 | |||
239 | /* Avoid taking the lock if we can */ | ||
240 | if (!gate_exists(gate)) | ||
241 | return true; | ||
242 | |||
243 | flags = ccu_lock(ccu); | ||
244 | ret = __is_clk_gate_enabled(ccu, gate); | ||
245 | ccu_unlock(ccu, flags); | ||
246 | |||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Commit our desired gate state to the hardware. | ||
252 | * Returns true if successful, false otherwise. | ||
253 | */ | ||
254 | static bool | ||
255 | __gate_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate) | ||
256 | { | ||
257 | u32 reg_val; | ||
258 | u32 mask; | ||
259 | bool enabled = false; | ||
260 | |||
261 | BUG_ON(!gate_exists(gate)); | ||
262 | if (!gate_is_sw_controllable(gate)) | ||
263 | return true; /* Nothing we can change */ | ||
264 | |||
265 | reg_val = __ccu_read(ccu, gate->offset); | ||
266 | |||
267 | /* For a hardware/software gate, set which is in control */ | ||
268 | if (gate_is_hw_controllable(gate)) { | ||
269 | mask = (u32)1 << gate->hw_sw_sel_bit; | ||
270 | if (gate_is_sw_managed(gate)) | ||
271 | reg_val |= mask; | ||
272 | else | ||
273 | reg_val &= ~mask; | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | * If software is in control, enable or disable the gate. | ||
278 | * If hardware is, clear the enabled bit for good measure. | ||
279 | * If a software controlled gate can't be disabled, we're | ||
280 | * required to write a 0 into the enable bit (but the gate | ||
281 | * will be enabled). | ||
282 | */ | ||
283 | mask = (u32)1 << gate->en_bit; | ||
284 | if (gate_is_sw_managed(gate) && (enabled = gate_is_enabled(gate)) && | ||
285 | !gate_is_no_disable(gate)) | ||
286 | reg_val |= mask; | ||
287 | else | ||
288 | reg_val &= ~mask; | ||
289 | |||
290 | __ccu_write(ccu, gate->offset, reg_val); | ||
291 | |||
292 | /* For a hardware controlled gate, we're done */ | ||
293 | if (!gate_is_sw_managed(gate)) | ||
294 | return true; | ||
295 | |||
296 | /* Otherwise wait for the gate to be in desired state */ | ||
297 | return __ccu_wait_bit(ccu, gate->offset, gate->status_bit, enabled); | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * Initialize a gate. Our desired state (hardware/software select, | ||
302 | * and if software, its enable state) is committed to hardware | ||
303 | * without the usual checks to see if it's already set up that way. | ||
304 | * Returns true if successful, false otherwise. | ||
305 | */ | ||
306 | static bool gate_init(struct ccu_data *ccu, struct bcm_clk_gate *gate) | ||
307 | { | ||
308 | if (!gate_exists(gate)) | ||
309 | return true; | ||
310 | return __gate_commit(ccu, gate); | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Set a gate to enabled or disabled state. Does nothing if the | ||
315 | * gate is not currently under software control, or if it is already | ||
316 | * in the requested state. Returns true if successful, false | ||
317 | * otherwise. CCU lock must be held. | ||
318 | */ | ||
319 | static bool | ||
320 | __clk_gate(struct ccu_data *ccu, struct bcm_clk_gate *gate, bool enable) | ||
321 | { | ||
322 | bool ret; | ||
323 | |||
324 | if (!gate_exists(gate) || !gate_is_sw_managed(gate)) | ||
325 | return true; /* Nothing to do */ | ||
326 | |||
327 | if (!enable && gate_is_no_disable(gate)) { | ||
328 | pr_warn("%s: invalid gate disable request (ignoring)\n", | ||
329 | __func__); | ||
330 | return true; | ||
331 | } | ||
332 | |||
333 | if (enable == gate_is_enabled(gate)) | ||
334 | return true; /* No change */ | ||
335 | |||
336 | gate_flip_enabled(gate); | ||
337 | ret = __gate_commit(ccu, gate); | ||
338 | if (!ret) | ||
339 | gate_flip_enabled(gate); /* Revert the change */ | ||
340 | |||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | /* Enable or disable a gate. Returns 0 if successful, -EIO otherwise */ | ||
345 | static int clk_gate(struct ccu_data *ccu, const char *name, | ||
346 | struct bcm_clk_gate *gate, bool enable) | ||
347 | { | ||
348 | unsigned long flags; | ||
349 | bool success; | ||
350 | |||
351 | /* | ||
352 | * Avoid taking the lock if we can. We quietly ignore | ||
353 | * requests to change state that don't make sense. | ||
354 | */ | ||
355 | if (!gate_exists(gate) || !gate_is_sw_managed(gate)) | ||
356 | return 0; | ||
357 | if (!enable && gate_is_no_disable(gate)) | ||
358 | return 0; | ||
359 | |||
360 | flags = ccu_lock(ccu); | ||
361 | __ccu_write_enable(ccu); | ||
362 | |||
363 | success = __clk_gate(ccu, gate, enable); | ||
364 | |||
365 | __ccu_write_disable(ccu); | ||
366 | ccu_unlock(ccu, flags); | ||
367 | |||
368 | if (success) | ||
369 | return 0; | ||
370 | |||
371 | pr_err("%s: failed to %s gate for %s\n", __func__, | ||
372 | enable ? "enable" : "disable", name); | ||
373 | |||
374 | return -EIO; | ||
375 | } | ||
376 | |||
377 | /* Trigger operations */ | ||
378 | |||
379 | /* | ||
380 | * Caller must ensure CCU lock is held and access is enabled. | ||
381 | * Returns true if successful, false otherwise. | ||
382 | */ | ||
383 | static bool __clk_trigger(struct ccu_data *ccu, struct bcm_clk_trig *trig) | ||
384 | { | ||
385 | /* Trigger the clock and wait for it to finish */ | ||
386 | __ccu_write(ccu, trig->offset, 1 << trig->bit); | ||
387 | |||
388 | return __ccu_wait_bit(ccu, trig->offset, trig->bit, false); | ||
389 | } | ||
390 | |||
391 | /* Divider operations */ | ||
392 | |||
393 | /* Read a divider value and return the scaled divisor it represents. */ | ||
394 | static u64 divider_read_scaled(struct ccu_data *ccu, struct bcm_clk_div *div) | ||
395 | { | ||
396 | unsigned long flags; | ||
397 | u32 reg_val; | ||
398 | u32 reg_div; | ||
399 | |||
400 | if (divider_is_fixed(div)) | ||
401 | return (u64)div->fixed; | ||
402 | |||
403 | flags = ccu_lock(ccu); | ||
404 | reg_val = __ccu_read(ccu, div->offset); | ||
405 | ccu_unlock(ccu, flags); | ||
406 | |||
407 | /* Extract the full divider field from the register value */ | ||
408 | reg_div = bitfield_extract(reg_val, div->shift, div->width); | ||
409 | |||
410 | /* Return the scaled divisor value it represents */ | ||
411 | return scaled_div_value(div, reg_div); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Convert a divider's scaled divisor value into its recorded form | ||
416 | * and commit it into the hardware divider register. | ||
417 | * | ||
418 | * Returns 0 on success. Returns -EINVAL for invalid arguments. | ||
419 | * Returns -ENXIO if gating failed, and -EIO if a trigger failed. | ||
420 | */ | ||
421 | static int __div_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate, | ||
422 | struct bcm_clk_div *div, struct bcm_clk_trig *trig) | ||
423 | { | ||
424 | bool enabled; | ||
425 | u32 reg_div; | ||
426 | u32 reg_val; | ||
427 | int ret = 0; | ||
428 | |||
429 | BUG_ON(divider_is_fixed(div)); | ||
430 | |||
431 | /* | ||
432 | * If we're just initializing the divider, and no initial | ||
433 | * state was defined in the device tree, we just find out | ||
434 | * what its current value is rather than updating it. | ||
435 | */ | ||
436 | if (div->scaled_div == BAD_SCALED_DIV_VALUE) { | ||
437 | reg_val = __ccu_read(ccu, div->offset); | ||
438 | reg_div = bitfield_extract(reg_val, div->shift, div->width); | ||
439 | div->scaled_div = scaled_div_value(div, reg_div); | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | /* Convert the scaled divisor to the value we need to record */ | ||
445 | reg_div = divider(div, div->scaled_div); | ||
446 | |||
447 | /* Clock needs to be enabled before changing the rate */ | ||
448 | enabled = __is_clk_gate_enabled(ccu, gate); | ||
449 | if (!enabled && !__clk_gate(ccu, gate, true)) { | ||
450 | ret = -ENXIO; | ||
451 | goto out; | ||
452 | } | ||
453 | |||
454 | /* Replace the divider value and record the result */ | ||
455 | reg_val = __ccu_read(ccu, div->offset); | ||
456 | reg_val = bitfield_replace(reg_val, div->shift, div->width, reg_div); | ||
457 | __ccu_write(ccu, div->offset, reg_val); | ||
458 | |||
459 | /* If the trigger fails we still want to disable the gate */ | ||
460 | if (!__clk_trigger(ccu, trig)) | ||
461 | ret = -EIO; | ||
462 | |||
463 | /* Disable the clock again if it was disabled to begin with */ | ||
464 | if (!enabled && !__clk_gate(ccu, gate, false)) | ||
465 | ret = ret ? ret : -ENXIO; /* return first error */ | ||
466 | out: | ||
467 | return ret; | ||
468 | } | ||
469 | |||
470 | /* | ||
471 | * Initialize a divider by committing our desired state to hardware | ||
472 | * without the usual checks to see if it's already set up that way. | ||
473 | * Returns true if successful, false otherwise. | ||
474 | */ | ||
475 | static bool div_init(struct ccu_data *ccu, struct bcm_clk_gate *gate, | ||
476 | struct bcm_clk_div *div, struct bcm_clk_trig *trig) | ||
477 | { | ||
478 | if (!divider_exists(div) || divider_is_fixed(div)) | ||
479 | return true; | ||
480 | return !__div_commit(ccu, gate, div, trig); | ||
481 | } | ||
482 | |||
483 | static int divider_write(struct ccu_data *ccu, struct bcm_clk_gate *gate, | ||
484 | struct bcm_clk_div *div, struct bcm_clk_trig *trig, | ||
485 | u64 scaled_div) | ||
486 | { | ||
487 | unsigned long flags; | ||
488 | u64 previous; | ||
489 | int ret; | ||
490 | |||
491 | BUG_ON(divider_is_fixed(div)); | ||
492 | |||
493 | previous = div->scaled_div; | ||
494 | if (previous == scaled_div) | ||
495 | return 0; /* No change */ | ||
496 | |||
497 | div->scaled_div = scaled_div; | ||
498 | |||
499 | flags = ccu_lock(ccu); | ||
500 | __ccu_write_enable(ccu); | ||
501 | |||
502 | ret = __div_commit(ccu, gate, div, trig); | ||
503 | |||
504 | __ccu_write_disable(ccu); | ||
505 | ccu_unlock(ccu, flags); | ||
506 | |||
507 | if (ret) | ||
508 | div->scaled_div = previous; /* Revert the change */ | ||
509 | |||
510 | return ret; | ||
511 | |||
512 | } | ||
513 | |||
514 | /* Common clock rate helpers */ | ||
515 | |||
516 | /* | ||
517 | * Implement the common clock framework recalc_rate method, taking | ||
518 | * into account a divider and an optional pre-divider. The | ||
519 | * pre-divider register pointer may be NULL. | ||
520 | */ | ||
521 | static unsigned long clk_recalc_rate(struct ccu_data *ccu, | ||
522 | struct bcm_clk_div *div, struct bcm_clk_div *pre_div, | ||
523 | unsigned long parent_rate) | ||
524 | { | ||
525 | u64 scaled_parent_rate; | ||
526 | u64 scaled_div; | ||
527 | u64 result; | ||
528 | |||
529 | if (!divider_exists(div)) | ||
530 | return parent_rate; | ||
531 | |||
532 | if (parent_rate > (unsigned long)LONG_MAX) | ||
533 | return 0; /* actually this would be a caller bug */ | ||
534 | |||
535 | /* | ||
536 | * If there is a pre-divider, divide the scaled parent rate | ||
537 | * by the pre-divider value first. In this case--to improve | ||
538 | * accuracy--scale the parent rate by *both* the pre-divider | ||
539 | * value and the divider before actually computing the | ||
540 | * result of the pre-divider. | ||
541 | * | ||
542 | * If there's only one divider, just scale the parent rate. | ||
543 | */ | ||
544 | if (pre_div && divider_exists(pre_div)) { | ||
545 | u64 scaled_rate; | ||
546 | |||
547 | scaled_rate = scale_rate(pre_div, parent_rate); | ||
548 | scaled_rate = scale_rate(div, scaled_rate); | ||
549 | scaled_div = divider_read_scaled(ccu, pre_div); | ||
550 | scaled_parent_rate = do_div_round_closest(scaled_rate, | ||
551 | scaled_div); | ||
552 | } else { | ||
553 | scaled_parent_rate = scale_rate(div, parent_rate); | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * Get the scaled divisor value, and divide the scaled | ||
558 | * parent rate by that to determine this clock's resulting | ||
559 | * rate. | ||
560 | */ | ||
561 | scaled_div = divider_read_scaled(ccu, div); | ||
562 | result = do_div_round_closest(scaled_parent_rate, scaled_div); | ||
563 | |||
564 | return (unsigned long)result; | ||
565 | } | ||
566 | |||
567 | /* | ||
568 | * Compute the output rate produced when a given parent rate is fed | ||
569 | * into two dividers. The pre-divider can be NULL, and even if it's | ||
570 | * non-null it may be nonexistent. It's also OK for the divider to | ||
571 | * be nonexistent, and in that case the pre-divider is also ignored. | ||
572 | * | ||
573 | * If scaled_div is non-null, it is used to return the scaled divisor | ||
574 | * value used by the (downstream) divider to produce that rate. | ||
575 | */ | ||
576 | static long round_rate(struct ccu_data *ccu, struct bcm_clk_div *div, | ||
577 | struct bcm_clk_div *pre_div, | ||
578 | unsigned long rate, unsigned long parent_rate, | ||
579 | u64 *scaled_div) | ||
580 | { | ||
581 | u64 scaled_parent_rate; | ||
582 | u64 min_scaled_div; | ||
583 | u64 max_scaled_div; | ||
584 | u64 best_scaled_div; | ||
585 | u64 result; | ||
586 | |||
587 | BUG_ON(!divider_exists(div)); | ||
588 | BUG_ON(!rate); | ||
589 | BUG_ON(parent_rate > (u64)LONG_MAX); | ||
590 | |||
591 | /* | ||
592 | * If there is a pre-divider, divide the scaled parent rate | ||
593 | * by the pre-divider value first. In this case--to improve | ||
594 | * accuracy--scale the parent rate by *both* the pre-divider | ||
595 | * value and the divider before actually computing the | ||
596 | * result of the pre-divider. | ||
597 | * | ||
598 | * If there's only one divider, just scale the parent rate. | ||
599 | * | ||
600 | * For simplicity we treat the pre-divider as fixed (for now). | ||
601 | */ | ||
602 | if (divider_exists(pre_div)) { | ||
603 | u64 scaled_rate; | ||
604 | u64 scaled_pre_div; | ||
605 | |||
606 | scaled_rate = scale_rate(pre_div, parent_rate); | ||
607 | scaled_rate = scale_rate(div, scaled_rate); | ||
608 | scaled_pre_div = divider_read_scaled(ccu, pre_div); | ||
609 | scaled_parent_rate = do_div_round_closest(scaled_rate, | ||
610 | scaled_pre_div); | ||
611 | } else { | ||
612 | scaled_parent_rate = scale_rate(div, parent_rate); | ||
613 | } | ||
614 | |||
615 | /* | ||
616 | * Compute the best possible divider and ensure it is in | ||
617 | * range. A fixed divider can't be changed, so just report | ||
618 | * the best we can do. | ||
619 | */ | ||
620 | if (!divider_is_fixed(div)) { | ||
621 | best_scaled_div = do_div_round_closest(scaled_parent_rate, | ||
622 | rate); | ||
623 | min_scaled_div = scaled_div_min(div); | ||
624 | max_scaled_div = scaled_div_max(div); | ||
625 | if (best_scaled_div > max_scaled_div) | ||
626 | best_scaled_div = max_scaled_div; | ||
627 | else if (best_scaled_div < min_scaled_div) | ||
628 | best_scaled_div = min_scaled_div; | ||
629 | } else { | ||
630 | best_scaled_div = divider_read_scaled(ccu, div); | ||
631 | } | ||
632 | |||
633 | /* OK, figure out the resulting rate */ | ||
634 | result = do_div_round_closest(scaled_parent_rate, best_scaled_div); | ||
635 | |||
636 | if (scaled_div) | ||
637 | *scaled_div = best_scaled_div; | ||
638 | |||
639 | return (long)result; | ||
640 | } | ||
641 | |||
642 | /* Common clock parent helpers */ | ||
643 | |||
644 | /* | ||
645 | * For a given parent selector (register field) value, find the | ||
646 | * index into a selector's parent_sel array that contains it. | ||
647 | * Returns the index, or BAD_CLK_INDEX if it's not found. | ||
648 | */ | ||
649 | static u8 parent_index(struct bcm_clk_sel *sel, u8 parent_sel) | ||
650 | { | ||
651 | u8 i; | ||
652 | |||
653 | BUG_ON(sel->parent_count > (u32)U8_MAX); | ||
654 | for (i = 0; i < sel->parent_count; i++) | ||
655 | if (sel->parent_sel[i] == parent_sel) | ||
656 | return i; | ||
657 | return BAD_CLK_INDEX; | ||
658 | } | ||
659 | |||
660 | /* | ||
661 | * Fetch the current value of the selector, and translate that into | ||
662 | * its corresponding index in the parent array we registered with | ||
663 | * the clock framework. | ||
664 | * | ||
665 | * Returns parent array index that corresponds with the value found, | ||
666 | * or BAD_CLK_INDEX if the found value is out of range. | ||
667 | */ | ||
668 | static u8 selector_read_index(struct ccu_data *ccu, struct bcm_clk_sel *sel) | ||
669 | { | ||
670 | unsigned long flags; | ||
671 | u32 reg_val; | ||
672 | u32 parent_sel; | ||
673 | u8 index; | ||
674 | |||
675 | /* If there's no selector, there's only one parent */ | ||
676 | if (!selector_exists(sel)) | ||
677 | return 0; | ||
678 | |||
679 | /* Get the value in the selector register */ | ||
680 | flags = ccu_lock(ccu); | ||
681 | reg_val = __ccu_read(ccu, sel->offset); | ||
682 | ccu_unlock(ccu, flags); | ||
683 | |||
684 | parent_sel = bitfield_extract(reg_val, sel->shift, sel->width); | ||
685 | |||
686 | /* Look up that selector's parent array index and return it */ | ||
687 | index = parent_index(sel, parent_sel); | ||
688 | if (index == BAD_CLK_INDEX) | ||
689 | pr_err("%s: out-of-range parent selector %u (%s 0x%04x)\n", | ||
690 | __func__, parent_sel, ccu->name, sel->offset); | ||
691 | |||
692 | return index; | ||
693 | } | ||
694 | |||
695 | /* | ||
696 | * Commit our desired selector value to the hardware. | ||
697 | * | ||
698 | * Returns 0 on success. Returns -EINVAL for invalid arguments. | ||
699 | * Returns -ENXIO if gating failed, and -EIO if a trigger failed. | ||
700 | */ | ||
701 | static int | ||
702 | __sel_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate, | ||
703 | struct bcm_clk_sel *sel, struct bcm_clk_trig *trig) | ||
704 | { | ||
705 | u32 parent_sel; | ||
706 | u32 reg_val; | ||
707 | bool enabled; | ||
708 | int ret = 0; | ||
709 | |||
710 | BUG_ON(!selector_exists(sel)); | ||
711 | |||
712 | /* | ||
713 | * If we're just initializing the selector, and no initial | ||
714 | * state was defined in the device tree, we just find out | ||
715 | * what its current value is rather than updating it. | ||
716 | */ | ||
717 | if (sel->clk_index == BAD_CLK_INDEX) { | ||
718 | u8 index; | ||
719 | |||
720 | reg_val = __ccu_read(ccu, sel->offset); | ||
721 | parent_sel = bitfield_extract(reg_val, sel->shift, sel->width); | ||
722 | index = parent_index(sel, parent_sel); | ||
723 | if (index == BAD_CLK_INDEX) | ||
724 | return -EINVAL; | ||
725 | sel->clk_index = index; | ||
726 | |||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | BUG_ON((u32)sel->clk_index >= sel->parent_count); | ||
731 | parent_sel = sel->parent_sel[sel->clk_index]; | ||
732 | |||
733 | /* Clock needs to be enabled before changing the parent */ | ||
734 | enabled = __is_clk_gate_enabled(ccu, gate); | ||
735 | if (!enabled && !__clk_gate(ccu, gate, true)) | ||
736 | return -ENXIO; | ||
737 | |||
738 | /* Replace the selector value and record the result */ | ||
739 | reg_val = __ccu_read(ccu, sel->offset); | ||
740 | reg_val = bitfield_replace(reg_val, sel->shift, sel->width, parent_sel); | ||
741 | __ccu_write(ccu, sel->offset, reg_val); | ||
742 | |||
743 | /* If the trigger fails we still want to disable the gate */ | ||
744 | if (!__clk_trigger(ccu, trig)) | ||
745 | ret = -EIO; | ||
746 | |||
747 | /* Disable the clock again if it was disabled to begin with */ | ||
748 | if (!enabled && !__clk_gate(ccu, gate, false)) | ||
749 | ret = ret ? ret : -ENXIO; /* return first error */ | ||
750 | |||
751 | return ret; | ||
752 | } | ||
753 | |||
754 | /* | ||
755 | * Initialize a selector by committing our desired state to hardware | ||
756 | * without the usual checks to see if it's already set up that way. | ||
757 | * Returns true if successful, false otherwise. | ||
758 | */ | ||
759 | static bool sel_init(struct ccu_data *ccu, struct bcm_clk_gate *gate, | ||
760 | struct bcm_clk_sel *sel, struct bcm_clk_trig *trig) | ||
761 | { | ||
762 | if (!selector_exists(sel)) | ||
763 | return true; | ||
764 | return !__sel_commit(ccu, gate, sel, trig); | ||
765 | } | ||
766 | |||
767 | /* | ||
768 | * Write a new value into a selector register to switch to a | ||
769 | * different parent clock. Returns 0 on success, or an error code | ||
770 | * (from __sel_commit()) otherwise. | ||
771 | */ | ||
772 | static int selector_write(struct ccu_data *ccu, struct bcm_clk_gate *gate, | ||
773 | struct bcm_clk_sel *sel, struct bcm_clk_trig *trig, | ||
774 | u8 index) | ||
775 | { | ||
776 | unsigned long flags; | ||
777 | u8 previous; | ||
778 | int ret; | ||
779 | |||
780 | previous = sel->clk_index; | ||
781 | if (previous == index) | ||
782 | return 0; /* No change */ | ||
783 | |||
784 | sel->clk_index = index; | ||
785 | |||
786 | flags = ccu_lock(ccu); | ||
787 | __ccu_write_enable(ccu); | ||
788 | |||
789 | ret = __sel_commit(ccu, gate, sel, trig); | ||
790 | |||
791 | __ccu_write_disable(ccu); | ||
792 | ccu_unlock(ccu, flags); | ||
793 | |||
794 | if (ret) | ||
795 | sel->clk_index = previous; /* Revert the change */ | ||
796 | |||
797 | return ret; | ||
798 | } | ||
799 | |||
800 | /* Clock operations */ | ||
801 | |||
802 | static int kona_peri_clk_enable(struct clk_hw *hw) | ||
803 | { | ||
804 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
805 | struct bcm_clk_gate *gate = &bcm_clk->peri->gate; | ||
806 | |||
807 | return clk_gate(bcm_clk->ccu, bcm_clk->name, gate, true); | ||
808 | } | ||
809 | |||
810 | static void kona_peri_clk_disable(struct clk_hw *hw) | ||
811 | { | ||
812 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
813 | struct bcm_clk_gate *gate = &bcm_clk->peri->gate; | ||
814 | |||
815 | (void)clk_gate(bcm_clk->ccu, bcm_clk->name, gate, false); | ||
816 | } | ||
817 | |||
818 | static int kona_peri_clk_is_enabled(struct clk_hw *hw) | ||
819 | { | ||
820 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
821 | struct bcm_clk_gate *gate = &bcm_clk->peri->gate; | ||
822 | |||
823 | return is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0; | ||
824 | } | ||
825 | |||
826 | static unsigned long kona_peri_clk_recalc_rate(struct clk_hw *hw, | ||
827 | unsigned long parent_rate) | ||
828 | { | ||
829 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
830 | struct peri_clk_data *data = bcm_clk->peri; | ||
831 | |||
832 | return clk_recalc_rate(bcm_clk->ccu, &data->div, &data->pre_div, | ||
833 | parent_rate); | ||
834 | } | ||
835 | |||
836 | static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
837 | unsigned long *parent_rate) | ||
838 | { | ||
839 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
840 | struct bcm_clk_div *div = &bcm_clk->peri->div; | ||
841 | |||
842 | if (!divider_exists(div)) | ||
843 | return __clk_get_rate(hw->clk); | ||
844 | |||
845 | /* Quietly avoid a zero rate */ | ||
846 | return round_rate(bcm_clk->ccu, div, &bcm_clk->peri->pre_div, | ||
847 | rate ? rate : 1, *parent_rate, NULL); | ||
848 | } | ||
849 | |||
850 | static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) | ||
851 | { | ||
852 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
853 | struct peri_clk_data *data = bcm_clk->peri; | ||
854 | struct bcm_clk_sel *sel = &data->sel; | ||
855 | struct bcm_clk_trig *trig; | ||
856 | int ret; | ||
857 | |||
858 | BUG_ON(index >= sel->parent_count); | ||
859 | |||
860 | /* If there's only one parent we don't require a selector */ | ||
861 | if (!selector_exists(sel)) | ||
862 | return 0; | ||
863 | |||
864 | /* | ||
865 | * The regular trigger is used by default, but if there's a | ||
866 | * pre-trigger we want to use that instead. | ||
867 | */ | ||
868 | trig = trigger_exists(&data->pre_trig) ? &data->pre_trig | ||
869 | : &data->trig; | ||
870 | |||
871 | ret = selector_write(bcm_clk->ccu, &data->gate, sel, trig, index); | ||
872 | if (ret == -ENXIO) { | ||
873 | pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name); | ||
874 | ret = -EIO; /* Don't proliferate weird errors */ | ||
875 | } else if (ret == -EIO) { | ||
876 | pr_err("%s: %strigger failed for %s\n", __func__, | ||
877 | trig == &data->pre_trig ? "pre-" : "", | ||
878 | bcm_clk->name); | ||
879 | } | ||
880 | |||
881 | return ret; | ||
882 | } | ||
883 | |||
884 | static u8 kona_peri_clk_get_parent(struct clk_hw *hw) | ||
885 | { | ||
886 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
887 | struct peri_clk_data *data = bcm_clk->peri; | ||
888 | u8 index; | ||
889 | |||
890 | index = selector_read_index(bcm_clk->ccu, &data->sel); | ||
891 | |||
892 | /* Not all callers would handle an out-of-range value gracefully */ | ||
893 | return index == BAD_CLK_INDEX ? 0 : index; | ||
894 | } | ||
895 | |||
896 | static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
897 | unsigned long parent_rate) | ||
898 | { | ||
899 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
900 | struct peri_clk_data *data = bcm_clk->peri; | ||
901 | struct bcm_clk_div *div = &data->div; | ||
902 | u64 scaled_div = 0; | ||
903 | int ret; | ||
904 | |||
905 | if (parent_rate > (unsigned long)LONG_MAX) | ||
906 | return -EINVAL; | ||
907 | |||
908 | if (rate == __clk_get_rate(hw->clk)) | ||
909 | return 0; | ||
910 | |||
911 | if (!divider_exists(div)) | ||
912 | return rate == parent_rate ? 0 : -EINVAL; | ||
913 | |||
914 | /* | ||
915 | * A fixed divider can't be changed. (Nor can a fixed | ||
916 | * pre-divider be, but for now we never actually try to | ||
917 | * change that.) Tolerate a request for a no-op change. | ||
918 | */ | ||
919 | if (divider_is_fixed(&data->div)) | ||
920 | return rate == parent_rate ? 0 : -EINVAL; | ||
921 | |||
922 | /* | ||
923 | * Get the scaled divisor value needed to achieve a clock | ||
924 | * rate as close as possible to what was requested, given | ||
925 | * the parent clock rate supplied. | ||
926 | */ | ||
927 | (void)round_rate(bcm_clk->ccu, div, &data->pre_div, | ||
928 | rate ? rate : 1, parent_rate, &scaled_div); | ||
929 | |||
930 | /* | ||
931 | * We aren't updating any pre-divider at this point, so | ||
932 | * we'll use the regular trigger. | ||
933 | */ | ||
934 | ret = divider_write(bcm_clk->ccu, &data->gate, &data->div, | ||
935 | &data->trig, scaled_div); | ||
936 | if (ret == -ENXIO) { | ||
937 | pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name); | ||
938 | ret = -EIO; /* Don't proliferate weird errors */ | ||
939 | } else if (ret == -EIO) { | ||
940 | pr_err("%s: trigger failed for %s\n", __func__, bcm_clk->name); | ||
941 | } | ||
942 | |||
943 | return ret; | ||
944 | } | ||
945 | |||
946 | struct clk_ops kona_peri_clk_ops = { | ||
947 | .enable = kona_peri_clk_enable, | ||
948 | .disable = kona_peri_clk_disable, | ||
949 | .is_enabled = kona_peri_clk_is_enabled, | ||
950 | .recalc_rate = kona_peri_clk_recalc_rate, | ||
951 | .round_rate = kona_peri_clk_round_rate, | ||
952 | .set_parent = kona_peri_clk_set_parent, | ||
953 | .get_parent = kona_peri_clk_get_parent, | ||
954 | .set_rate = kona_peri_clk_set_rate, | ||
955 | }; | ||
956 | |||
957 | /* Put a peripheral clock into its initial state */ | ||
958 | static bool __peri_clk_init(struct kona_clk *bcm_clk) | ||
959 | { | ||
960 | struct ccu_data *ccu = bcm_clk->ccu; | ||
961 | struct peri_clk_data *peri = bcm_clk->peri; | ||
962 | const char *name = bcm_clk->name; | ||
963 | struct bcm_clk_trig *trig; | ||
964 | |||
965 | BUG_ON(bcm_clk->type != bcm_clk_peri); | ||
966 | |||
967 | if (!gate_init(ccu, &peri->gate)) { | ||
968 | pr_err("%s: error initializing gate for %s\n", __func__, name); | ||
969 | return false; | ||
970 | } | ||
971 | if (!div_init(ccu, &peri->gate, &peri->div, &peri->trig)) { | ||
972 | pr_err("%s: error initializing divider for %s\n", __func__, | ||
973 | name); | ||
974 | return false; | ||
975 | } | ||
976 | |||
977 | /* | ||
978 | * For the pre-divider and selector, the pre-trigger is used | ||
979 | * if it's present, otherwise we just use the regular trigger. | ||
980 | */ | ||
981 | trig = trigger_exists(&peri->pre_trig) ? &peri->pre_trig | ||
982 | : &peri->trig; | ||
983 | |||
984 | if (!div_init(ccu, &peri->gate, &peri->pre_div, trig)) { | ||
985 | pr_err("%s: error initializing pre-divider for %s\n", __func__, | ||
986 | name); | ||
987 | return false; | ||
988 | } | ||
989 | |||
990 | if (!sel_init(ccu, &peri->gate, &peri->sel, trig)) { | ||
991 | pr_err("%s: error initializing selector for %s\n", __func__, | ||
992 | name); | ||
993 | return false; | ||
994 | } | ||
995 | |||
996 | return true; | ||
997 | } | ||
998 | |||
999 | static bool __kona_clk_init(struct kona_clk *bcm_clk) | ||
1000 | { | ||
1001 | switch (bcm_clk->type) { | ||
1002 | case bcm_clk_peri: | ||
1003 | return __peri_clk_init(bcm_clk); | ||
1004 | default: | ||
1005 | BUG(); | ||
1006 | } | ||
1007 | return -EINVAL; | ||
1008 | } | ||
1009 | |||
1010 | /* Set a CCU and all its clocks into their desired initial state */ | ||
1011 | bool __init kona_ccu_init(struct ccu_data *ccu) | ||
1012 | { | ||
1013 | unsigned long flags; | ||
1014 | unsigned int which; | ||
1015 | struct clk **clks = ccu->data.clks; | ||
1016 | bool success = true; | ||
1017 | |||
1018 | flags = ccu_lock(ccu); | ||
1019 | __ccu_write_enable(ccu); | ||
1020 | |||
1021 | for (which = 0; which < ccu->data.clk_num; which++) { | ||
1022 | struct kona_clk *bcm_clk; | ||
1023 | |||
1024 | if (!clks[which]) | ||
1025 | continue; | ||
1026 | bcm_clk = to_kona_clk(__clk_get_hw(clks[which])); | ||
1027 | success &= __kona_clk_init(bcm_clk); | ||
1028 | } | ||
1029 | |||
1030 | __ccu_write_disable(ccu); | ||
1031 | ccu_unlock(ccu, flags); | ||
1032 | return success; | ||
1033 | } | ||
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h new file mode 100644 index 000000000000..5e139adc3dc5 --- /dev/null +++ b/drivers/clk/bcm/clk-kona.h | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * Copyright 2013 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation version 2. | ||
8 | * | ||
9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
10 | * kind, whether express or implied; without even the implied warranty | ||
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _CLK_KONA_H | ||
16 | #define _CLK_KONA_H | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/clk-provider.h> | ||
25 | |||
26 | #define BILLION 1000000000 | ||
27 | |||
28 | /* The common clock framework uses u8 to represent a parent index */ | ||
29 | #define PARENT_COUNT_MAX ((u32)U8_MAX) | ||
30 | |||
31 | #define BAD_CLK_INDEX U8_MAX /* Can't ever be valid */ | ||
32 | #define BAD_CLK_NAME ((const char *)-1) | ||
33 | |||
34 | #define BAD_SCALED_DIV_VALUE U64_MAX | ||
35 | |||
36 | /* | ||
37 | * Utility macros for object flag management. If possible, flags | ||
38 | * should be defined such that 0 is the desired default value. | ||
39 | */ | ||
40 | #define FLAG(type, flag) BCM_CLK_ ## type ## _FLAGS_ ## flag | ||
41 | #define FLAG_SET(obj, type, flag) ((obj)->flags |= FLAG(type, flag)) | ||
42 | #define FLAG_CLEAR(obj, type, flag) ((obj)->flags &= ~(FLAG(type, flag))) | ||
43 | #define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag)) | ||
44 | #define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag))) | ||
45 | |||
46 | /* Clock field state tests */ | ||
47 | |||
48 | #define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS) | ||
49 | #define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED) | ||
50 | #define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW) | ||
51 | #define gate_is_sw_controllable(gate) FLAG_TEST(gate, GATE, SW) | ||
52 | #define gate_is_sw_managed(gate) FLAG_TEST(gate, GATE, SW_MANAGED) | ||
53 | #define gate_is_no_disable(gate) FLAG_TEST(gate, GATE, NO_DISABLE) | ||
54 | |||
55 | #define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED) | ||
56 | |||
57 | #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) | ||
58 | #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) | ||
59 | #define divider_has_fraction(div) (!divider_is_fixed(div) && \ | ||
60 | (div)->frac_width > 0) | ||
61 | |||
62 | #define selector_exists(sel) ((sel)->width != 0) | ||
63 | #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) | ||
64 | |||
65 | /* Clock type, used to tell common block what it's part of */ | ||
66 | enum bcm_clk_type { | ||
67 | bcm_clk_none, /* undefined clock type */ | ||
68 | bcm_clk_bus, | ||
69 | bcm_clk_core, | ||
70 | bcm_clk_peri | ||
71 | }; | ||
72 | |||
73 | /* | ||
74 | * Each CCU defines a mapped area of memory containing registers | ||
75 | * used to manage clocks implemented by the CCU. Access to memory | ||
76 | * within the CCU's space is serialized by a spinlock. Before any | ||
77 | * (other) address can be written, a special access "password" value | ||
78 | * must be written to its WR_ACCESS register (located at the base | ||
79 | * address of the range). We keep track of the name of each CCU as | ||
80 | * it is set up, and maintain them in a list. | ||
81 | */ | ||
82 | struct ccu_data { | ||
83 | void __iomem *base; /* base of mapped address space */ | ||
84 | spinlock_t lock; /* serialization lock */ | ||
85 | bool write_enabled; /* write access is currently enabled */ | ||
86 | struct list_head links; /* for ccu_list */ | ||
87 | struct device_node *node; | ||
88 | struct clk_onecell_data data; | ||
89 | const char *name; | ||
90 | u32 range; /* byte range of address space */ | ||
91 | }; | ||
92 | |||
93 | /* | ||
94 | * Gating control and status is managed by a 32-bit gate register. | ||
95 | * | ||
96 | * There are several types of gating available: | ||
97 | * - (no gate) | ||
98 | * A clock with no gate is assumed to be always enabled. | ||
99 | * - hardware-only gating (auto-gating) | ||
100 | * Enabling or disabling clocks with this type of gate is | ||
101 | * managed automatically by the hardware. Such clocks can be | ||
102 | * considered by the software to be enabled. The current status | ||
103 | * of auto-gated clocks can be read from the gate status bit. | ||
104 | * - software-only gating | ||
105 | * Auto-gating is not available for this type of clock. | ||
106 | * Instead, software manages whether it's enabled by setting or | ||
107 | * clearing the enable bit. The current gate status of a gate | ||
108 | * under software control can be read from the gate status bit. | ||
109 | * To ensure a change to the gating status is complete, the | ||
110 | * status bit can be polled to verify that the gate has entered | ||
111 | * the desired state. | ||
112 | * - selectable hardware or software gating | ||
113 | * Gating for this type of clock can be configured to be either | ||
114 | * under software or hardware control. Which type is in use is | ||
115 | * determined by the hw_sw_sel bit of the gate register. | ||
116 | */ | ||
117 | struct bcm_clk_gate { | ||
118 | u32 offset; /* gate register offset */ | ||
119 | u32 status_bit; /* 0: gate is disabled; 0: gatge is enabled */ | ||
120 | u32 en_bit; /* 0: disable; 1: enable */ | ||
121 | u32 hw_sw_sel_bit; /* 0: hardware gating; 1: software gating */ | ||
122 | u32 flags; /* BCM_CLK_GATE_FLAGS_* below */ | ||
123 | }; | ||
124 | |||
125 | /* | ||
126 | * Gate flags: | ||
127 | * HW means this gate can be auto-gated | ||
128 | * SW means the state of this gate can be software controlled | ||
129 | * NO_DISABLE means this gate is (only) enabled if under software control | ||
130 | * SW_MANAGED means the status of this gate is under software control | ||
131 | * ENABLED means this software-managed gate is *supposed* to be enabled | ||
132 | */ | ||
133 | #define BCM_CLK_GATE_FLAGS_EXISTS ((u32)1 << 0) /* Gate is valid */ | ||
134 | #define BCM_CLK_GATE_FLAGS_HW ((u32)1 << 1) /* Can auto-gate */ | ||
135 | #define BCM_CLK_GATE_FLAGS_SW ((u32)1 << 2) /* Software control */ | ||
136 | #define BCM_CLK_GATE_FLAGS_NO_DISABLE ((u32)1 << 3) /* HW or enabled */ | ||
137 | #define BCM_CLK_GATE_FLAGS_SW_MANAGED ((u32)1 << 4) /* SW now in control */ | ||
138 | #define BCM_CLK_GATE_FLAGS_ENABLED ((u32)1 << 5) /* If SW_MANAGED */ | ||
139 | |||
140 | /* | ||
141 | * Gate initialization macros. | ||
142 | * | ||
143 | * Any gate initially under software control will be enabled. | ||
144 | */ | ||
145 | |||
146 | /* A hardware/software gate initially under software control */ | ||
147 | #define HW_SW_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \ | ||
148 | { \ | ||
149 | .offset = (_offset), \ | ||
150 | .status_bit = (_status_bit), \ | ||
151 | .en_bit = (_en_bit), \ | ||
152 | .hw_sw_sel_bit = (_hw_sw_sel_bit), \ | ||
153 | .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \ | ||
154 | FLAG(GATE, SW_MANAGED)|FLAG(GATE, ENABLED)| \ | ||
155 | FLAG(GATE, EXISTS), \ | ||
156 | } | ||
157 | |||
158 | /* A hardware/software gate initially under hardware control */ | ||
159 | #define HW_SW_GATE_AUTO(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \ | ||
160 | { \ | ||
161 | .offset = (_offset), \ | ||
162 | .status_bit = (_status_bit), \ | ||
163 | .en_bit = (_en_bit), \ | ||
164 | .hw_sw_sel_bit = (_hw_sw_sel_bit), \ | ||
165 | .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \ | ||
166 | FLAG(GATE, EXISTS), \ | ||
167 | } | ||
168 | |||
169 | /* A hardware-or-enabled gate (enabled if not under hardware control) */ | ||
170 | #define HW_ENABLE_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \ | ||
171 | { \ | ||
172 | .offset = (_offset), \ | ||
173 | .status_bit = (_status_bit), \ | ||
174 | .en_bit = (_en_bit), \ | ||
175 | .hw_sw_sel_bit = (_hw_sw_sel_bit), \ | ||
176 | .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \ | ||
177 | FLAG(GATE, NO_DISABLE)|FLAG(GATE, EXISTS), \ | ||
178 | } | ||
179 | |||
180 | /* A software-only gate */ | ||
181 | #define SW_ONLY_GATE(_offset, _status_bit, _en_bit) \ | ||
182 | { \ | ||
183 | .offset = (_offset), \ | ||
184 | .status_bit = (_status_bit), \ | ||
185 | .en_bit = (_en_bit), \ | ||
186 | .flags = FLAG(GATE, SW)|FLAG(GATE, SW_MANAGED)| \ | ||
187 | FLAG(GATE, ENABLED)|FLAG(GATE, EXISTS), \ | ||
188 | } | ||
189 | |||
190 | /* A hardware-only gate */ | ||
191 | #define HW_ONLY_GATE(_offset, _status_bit) \ | ||
192 | { \ | ||
193 | .offset = (_offset), \ | ||
194 | .status_bit = (_status_bit), \ | ||
195 | .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \ | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Each clock can have zero, one, or two dividers which change the | ||
200 | * output rate of the clock. Each divider can be either fixed or | ||
201 | * variable. If there are two dividers, they are the "pre-divider" | ||
202 | * and the "regular" or "downstream" divider. If there is only one, | ||
203 | * there is no pre-divider. | ||
204 | * | ||
205 | * A fixed divider is any non-zero (positive) value, and it | ||
206 | * indicates how the input rate is affected by the divider. | ||
207 | * | ||
208 | * The value of a variable divider is maintained in a sub-field of a | ||
209 | * 32-bit divider register. The position of the field in the | ||
210 | * register is defined by its offset and width. The value recorded | ||
211 | * in this field is always 1 less than the value it represents. | ||
212 | * | ||
213 | * In addition, a variable divider can indicate that some subset | ||
214 | * of its bits represent a "fractional" part of the divider. Such | ||
215 | * bits comprise the low-order portion of the divider field, and can | ||
216 | * be viewed as representing the portion of the divider that lies to | ||
217 | * the right of the decimal point. Most variable dividers have zero | ||
218 | * fractional bits. Variable dividers with non-zero fraction width | ||
219 | * still record a value 1 less than the value they represent; the | ||
220 | * added 1 does *not* affect the low-order bit in this case, it | ||
221 | * affects the bits above the fractional part only. (Often in this | ||
222 | * code a divider field value is distinguished from the value it | ||
223 | * represents by referring to the latter as a "divisor".) | ||
224 | * | ||
225 | * In order to avoid dealing with fractions, divider arithmetic is | ||
226 | * performed using "scaled" values. A scaled value is one that's | ||
227 | * been left-shifted by the fractional width of a divider. Dividing | ||
228 | * a scaled value by a scaled divisor produces the desired quotient | ||
229 | * without loss of precision and without any other special handling | ||
230 | * for fractions. | ||
231 | * | ||
232 | * The recorded value of a variable divider can be modified. To | ||
233 | * modify either divider (or both), a clock must be enabled (i.e., | ||
234 | * using its gate). In addition, a trigger register (described | ||
235 | * below) must be used to commit the change, and polled to verify | ||
236 | * the change is complete. | ||
237 | */ | ||
238 | struct bcm_clk_div { | ||
239 | union { | ||
240 | struct { /* variable divider */ | ||
241 | u32 offset; /* divider register offset */ | ||
242 | u32 shift; /* field shift */ | ||
243 | u32 width; /* field width */ | ||
244 | u32 frac_width; /* field fraction width */ | ||
245 | |||
246 | u64 scaled_div; /* scaled divider value */ | ||
247 | }; | ||
248 | u32 fixed; /* non-zero fixed divider value */ | ||
249 | }; | ||
250 | u32 flags; /* BCM_CLK_DIV_FLAGS_* below */ | ||
251 | }; | ||
252 | |||
253 | /* | ||
254 | * Divider flags: | ||
255 | * EXISTS means this divider exists | ||
256 | * FIXED means it is a fixed-rate divider | ||
257 | */ | ||
258 | #define BCM_CLK_DIV_FLAGS_EXISTS ((u32)1 << 0) /* Divider is valid */ | ||
259 | #define BCM_CLK_DIV_FLAGS_FIXED ((u32)1 << 1) /* Fixed-value */ | ||
260 | |||
261 | /* Divider initialization macros */ | ||
262 | |||
263 | /* A fixed (non-zero) divider */ | ||
264 | #define FIXED_DIVIDER(_value) \ | ||
265 | { \ | ||
266 | .fixed = (_value), \ | ||
267 | .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED), \ | ||
268 | } | ||
269 | |||
270 | /* A divider with an integral divisor */ | ||
271 | #define DIVIDER(_offset, _shift, _width) \ | ||
272 | { \ | ||
273 | .offset = (_offset), \ | ||
274 | .shift = (_shift), \ | ||
275 | .width = (_width), \ | ||
276 | .scaled_div = BAD_SCALED_DIV_VALUE, \ | ||
277 | .flags = FLAG(DIV, EXISTS), \ | ||
278 | } | ||
279 | |||
280 | /* A divider whose divisor has an integer and fractional part */ | ||
281 | #define FRAC_DIVIDER(_offset, _shift, _width, _frac_width) \ | ||
282 | { \ | ||
283 | .offset = (_offset), \ | ||
284 | .shift = (_shift), \ | ||
285 | .width = (_width), \ | ||
286 | .frac_width = (_frac_width), \ | ||
287 | .scaled_div = BAD_SCALED_DIV_VALUE, \ | ||
288 | .flags = FLAG(DIV, EXISTS), \ | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Clocks may have multiple "parent" clocks. If there is more than | ||
293 | * one, a selector must be specified to define which of the parent | ||
294 | * clocks is currently in use. The selected clock is indicated in a | ||
295 | * sub-field of a 32-bit selector register. The range of | ||
296 | * representable selector values typically exceeds the number of | ||
297 | * available parent clocks. Occasionally the reset value of a | ||
298 | * selector field is explicitly set to a (specific) value that does | ||
299 | * not correspond to a defined input clock. | ||
300 | * | ||
301 | * We register all known parent clocks with the common clock code | ||
302 | * using a packed array (i.e., no empty slots) of (parent) clock | ||
303 | * names, and refer to them later using indexes into that array. | ||
304 | * We maintain an array of selector values indexed by common clock | ||
305 | * index values in order to map between these common clock indexes | ||
306 | * and the selector values used by the hardware. | ||
307 | * | ||
308 | * Like dividers, a selector can be modified, but to do so a clock | ||
309 | * must be enabled, and a trigger must be used to commit the change. | ||
310 | */ | ||
311 | struct bcm_clk_sel { | ||
312 | u32 offset; /* selector register offset */ | ||
313 | u32 shift; /* field shift */ | ||
314 | u32 width; /* field width */ | ||
315 | |||
316 | u32 parent_count; /* number of entries in parent_sel[] */ | ||
317 | u32 *parent_sel; /* array of parent selector values */ | ||
318 | u8 clk_index; /* current selected index in parent_sel[] */ | ||
319 | }; | ||
320 | |||
321 | /* Selector initialization macro */ | ||
322 | #define SELECTOR(_offset, _shift, _width) \ | ||
323 | { \ | ||
324 | .offset = (_offset), \ | ||
325 | .shift = (_shift), \ | ||
326 | .width = (_width), \ | ||
327 | .clk_index = BAD_CLK_INDEX, \ | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * Making changes to a variable divider or a selector for a clock | ||
332 | * requires the use of a trigger. A trigger is defined by a single | ||
333 | * bit within a register. To signal a change, a 1 is written into | ||
334 | * that bit. To determine when the change has been completed, that | ||
335 | * trigger bit is polled; the read value will be 1 while the change | ||
336 | * is in progress, and 0 when it is complete. | ||
337 | * | ||
338 | * Occasionally a clock will have more than one trigger. In this | ||
339 | * case, the "pre-trigger" will be used when changing a clock's | ||
340 | * selector and/or its pre-divider. | ||
341 | */ | ||
342 | struct bcm_clk_trig { | ||
343 | u32 offset; /* trigger register offset */ | ||
344 | u32 bit; /* trigger bit */ | ||
345 | u32 flags; /* BCM_CLK_TRIG_FLAGS_* below */ | ||
346 | }; | ||
347 | |||
348 | /* | ||
349 | * Trigger flags: | ||
350 | * EXISTS means this trigger exists | ||
351 | */ | ||
352 | #define BCM_CLK_TRIG_FLAGS_EXISTS ((u32)1 << 0) /* Trigger is valid */ | ||
353 | |||
354 | /* Trigger initialization macro */ | ||
355 | #define TRIGGER(_offset, _bit) \ | ||
356 | { \ | ||
357 | .offset = (_offset), \ | ||
358 | .bit = (_bit), \ | ||
359 | .flags = FLAG(TRIG, EXISTS), \ | ||
360 | } | ||
361 | |||
362 | struct peri_clk_data { | ||
363 | struct bcm_clk_gate gate; | ||
364 | struct bcm_clk_trig pre_trig; | ||
365 | struct bcm_clk_div pre_div; | ||
366 | struct bcm_clk_trig trig; | ||
367 | struct bcm_clk_div div; | ||
368 | struct bcm_clk_sel sel; | ||
369 | const char *clocks[]; /* must be last; use CLOCKS() to declare */ | ||
370 | }; | ||
371 | #define CLOCKS(...) { __VA_ARGS__, NULL, } | ||
372 | #define NO_CLOCKS { NULL, } /* Must use of no parent clocks */ | ||
373 | |||
374 | struct kona_clk { | ||
375 | struct clk_hw hw; | ||
376 | struct clk_init_data init_data; | ||
377 | const char *name; /* name of this clock */ | ||
378 | struct ccu_data *ccu; /* ccu this clock is associated with */ | ||
379 | enum bcm_clk_type type; | ||
380 | union { | ||
381 | void *data; | ||
382 | struct peri_clk_data *peri; | ||
383 | }; | ||
384 | }; | ||
385 | #define to_kona_clk(_hw) \ | ||
386 | container_of(_hw, struct kona_clk, hw) | ||
387 | |||
388 | /* Exported globals */ | ||
389 | |||
390 | extern struct clk_ops kona_peri_clk_ops; | ||
391 | |||
392 | /* Help functions */ | ||
393 | |||
394 | #define PERI_CLK_SETUP(clks, ccu, id, name) \ | ||
395 | clks[id] = kona_clk_setup(ccu, #name, bcm_clk_peri, &name ## _data) | ||
396 | |||
397 | /* Externally visible functions */ | ||
398 | |||
399 | extern u64 do_div_round_closest(u64 dividend, unsigned long divisor); | ||
400 | extern u64 scaled_div_max(struct bcm_clk_div *div); | ||
401 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, | ||
402 | u32 billionths); | ||
403 | |||
404 | extern struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | ||
405 | enum bcm_clk_type type, void *data); | ||
406 | extern void __init kona_dt_ccu_setup(struct device_node *node, | ||
407 | int (*ccu_clks_setup)(struct ccu_data *)); | ||
408 | extern bool __init kona_ccu_init(struct ccu_data *ccu); | ||
409 | |||
410 | #endif /* _CLK_KONA_H */ | ||
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 010f071af883..b4f967210175 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/clk-provider.h> | 16 | #include <linux/clk-provider.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/syscore_ops.h> | ||
19 | 20 | ||
20 | #include "clk.h" | 21 | #include "clk.h" |
21 | 22 | ||
@@ -130,6 +131,17 @@ enum exynos4_plls { | |||
130 | nr_plls /* number of PLLs */ | 131 | nr_plls /* number of PLLs */ |
131 | }; | 132 | }; |
132 | 133 | ||
134 | static void __iomem *reg_base; | ||
135 | static enum exynos4_soc exynos4_soc; | ||
136 | |||
137 | /* | ||
138 | * Support for CMU save/restore across system suspends | ||
139 | */ | ||
140 | #ifdef CONFIG_PM_SLEEP | ||
141 | static struct samsung_clk_reg_dump *exynos4_save_common; | ||
142 | static struct samsung_clk_reg_dump *exynos4_save_soc; | ||
143 | static struct samsung_clk_reg_dump *exynos4_save_pll; | ||
144 | |||
133 | /* | 145 | /* |
134 | * list of controller registers to be saved and restored during a | 146 | * list of controller registers to be saved and restored during a |
135 | * suspend/resume cycle. | 147 | * suspend/resume cycle. |
@@ -154,6 +166,17 @@ static unsigned long exynos4x12_clk_save[] __initdata = { | |||
154 | E4X12_MPLL_CON0, | 166 | E4X12_MPLL_CON0, |
155 | }; | 167 | }; |
156 | 168 | ||
169 | static unsigned long exynos4_clk_pll_regs[] __initdata = { | ||
170 | EPLL_LOCK, | ||
171 | VPLL_LOCK, | ||
172 | EPLL_CON0, | ||
173 | EPLL_CON1, | ||
174 | EPLL_CON2, | ||
175 | VPLL_CON0, | ||
176 | VPLL_CON1, | ||
177 | VPLL_CON2, | ||
178 | }; | ||
179 | |||
157 | static unsigned long exynos4_clk_regs[] __initdata = { | 180 | static unsigned long exynos4_clk_regs[] __initdata = { |
158 | SRC_LEFTBUS, | 181 | SRC_LEFTBUS, |
159 | DIV_LEFTBUS, | 182 | DIV_LEFTBUS, |
@@ -161,12 +184,6 @@ static unsigned long exynos4_clk_regs[] __initdata = { | |||
161 | SRC_RIGHTBUS, | 184 | SRC_RIGHTBUS, |
162 | DIV_RIGHTBUS, | 185 | DIV_RIGHTBUS, |
163 | GATE_IP_RIGHTBUS, | 186 | GATE_IP_RIGHTBUS, |
164 | EPLL_CON0, | ||
165 | EPLL_CON1, | ||
166 | EPLL_CON2, | ||
167 | VPLL_CON0, | ||
168 | VPLL_CON1, | ||
169 | VPLL_CON2, | ||
170 | SRC_TOP0, | 187 | SRC_TOP0, |
171 | SRC_TOP1, | 188 | SRC_TOP1, |
172 | SRC_CAM, | 189 | SRC_CAM, |
@@ -227,6 +244,124 @@ static unsigned long exynos4_clk_regs[] __initdata = { | |||
227 | GATE_IP_CPU, | 244 | GATE_IP_CPU, |
228 | }; | 245 | }; |
229 | 246 | ||
247 | static const struct samsung_clk_reg_dump src_mask_suspend[] = { | ||
248 | { .offset = SRC_MASK_TOP, .value = 0x00000001, }, | ||
249 | { .offset = SRC_MASK_CAM, .value = 0x11111111, }, | ||
250 | { .offset = SRC_MASK_TV, .value = 0x00000111, }, | ||
251 | { .offset = SRC_MASK_LCD0, .value = 0x00001111, }, | ||
252 | { .offset = SRC_MASK_MAUDIO, .value = 0x00000001, }, | ||
253 | { .offset = SRC_MASK_FSYS, .value = 0x01011111, }, | ||
254 | { .offset = SRC_MASK_PERIL0, .value = 0x01111111, }, | ||
255 | { .offset = SRC_MASK_PERIL1, .value = 0x01110111, }, | ||
256 | { .offset = SRC_MASK_DMC, .value = 0x00010000, }, | ||
257 | }; | ||
258 | |||
259 | static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = { | ||
260 | { .offset = E4210_SRC_MASK_LCD1, .value = 0x00001111, }, | ||
261 | }; | ||
262 | |||
263 | #define PLL_ENABLED (1 << 31) | ||
264 | #define PLL_LOCKED (1 << 29) | ||
265 | |||
266 | static void exynos4_clk_wait_for_pll(u32 reg) | ||
267 | { | ||
268 | u32 pll_con; | ||
269 | |||
270 | pll_con = readl(reg_base + reg); | ||
271 | if (!(pll_con & PLL_ENABLED)) | ||
272 | return; | ||
273 | |||
274 | while (!(pll_con & PLL_LOCKED)) { | ||
275 | cpu_relax(); | ||
276 | pll_con = readl(reg_base + reg); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | static int exynos4_clk_suspend(void) | ||
281 | { | ||
282 | samsung_clk_save(reg_base, exynos4_save_common, | ||
283 | ARRAY_SIZE(exynos4_clk_regs)); | ||
284 | samsung_clk_save(reg_base, exynos4_save_pll, | ||
285 | ARRAY_SIZE(exynos4_clk_pll_regs)); | ||
286 | |||
287 | if (exynos4_soc == EXYNOS4210) { | ||
288 | samsung_clk_save(reg_base, exynos4_save_soc, | ||
289 | ARRAY_SIZE(exynos4210_clk_save)); | ||
290 | samsung_clk_restore(reg_base, src_mask_suspend_e4210, | ||
291 | ARRAY_SIZE(src_mask_suspend_e4210)); | ||
292 | } else { | ||
293 | samsung_clk_save(reg_base, exynos4_save_soc, | ||
294 | ARRAY_SIZE(exynos4x12_clk_save)); | ||
295 | } | ||
296 | |||
297 | samsung_clk_restore(reg_base, src_mask_suspend, | ||
298 | ARRAY_SIZE(src_mask_suspend)); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static void exynos4_clk_resume(void) | ||
304 | { | ||
305 | samsung_clk_restore(reg_base, exynos4_save_pll, | ||
306 | ARRAY_SIZE(exynos4_clk_pll_regs)); | ||
307 | |||
308 | exynos4_clk_wait_for_pll(EPLL_CON0); | ||
309 | exynos4_clk_wait_for_pll(VPLL_CON0); | ||
310 | |||
311 | samsung_clk_restore(reg_base, exynos4_save_common, | ||
312 | ARRAY_SIZE(exynos4_clk_regs)); | ||
313 | |||
314 | if (exynos4_soc == EXYNOS4210) | ||
315 | samsung_clk_restore(reg_base, exynos4_save_soc, | ||
316 | ARRAY_SIZE(exynos4210_clk_save)); | ||
317 | else | ||
318 | samsung_clk_restore(reg_base, exynos4_save_soc, | ||
319 | ARRAY_SIZE(exynos4x12_clk_save)); | ||
320 | } | ||
321 | |||
322 | static struct syscore_ops exynos4_clk_syscore_ops = { | ||
323 | .suspend = exynos4_clk_suspend, | ||
324 | .resume = exynos4_clk_resume, | ||
325 | }; | ||
326 | |||
327 | static void exynos4_clk_sleep_init(void) | ||
328 | { | ||
329 | exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs, | ||
330 | ARRAY_SIZE(exynos4_clk_regs)); | ||
331 | if (!exynos4_save_common) | ||
332 | goto err_warn; | ||
333 | |||
334 | if (exynos4_soc == EXYNOS4210) | ||
335 | exynos4_save_soc = samsung_clk_alloc_reg_dump( | ||
336 | exynos4210_clk_save, | ||
337 | ARRAY_SIZE(exynos4210_clk_save)); | ||
338 | else | ||
339 | exynos4_save_soc = samsung_clk_alloc_reg_dump( | ||
340 | exynos4x12_clk_save, | ||
341 | ARRAY_SIZE(exynos4x12_clk_save)); | ||
342 | if (!exynos4_save_soc) | ||
343 | goto err_common; | ||
344 | |||
345 | exynos4_save_pll = samsung_clk_alloc_reg_dump(exynos4_clk_pll_regs, | ||
346 | ARRAY_SIZE(exynos4_clk_pll_regs)); | ||
347 | if (!exynos4_save_pll) | ||
348 | goto err_soc; | ||
349 | |||
350 | register_syscore_ops(&exynos4_clk_syscore_ops); | ||
351 | return; | ||
352 | |||
353 | err_soc: | ||
354 | kfree(exynos4_save_soc); | ||
355 | err_common: | ||
356 | kfree(exynos4_save_common); | ||
357 | err_warn: | ||
358 | pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", | ||
359 | __func__); | ||
360 | } | ||
361 | #else | ||
362 | static void exynos4_clk_sleep_init(void) {} | ||
363 | #endif | ||
364 | |||
230 | /* list of all parent clock list */ | 365 | /* list of all parent clock list */ |
231 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; | 366 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; |
232 | PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; | 367 | PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; |
@@ -908,12 +1043,13 @@ static unsigned long exynos4_get_xom(void) | |||
908 | return xom; | 1043 | return xom; |
909 | } | 1044 | } |
910 | 1045 | ||
911 | static void __init exynos4_clk_register_finpll(unsigned long xom) | 1046 | static void __init exynos4_clk_register_finpll(void) |
912 | { | 1047 | { |
913 | struct samsung_fixed_rate_clock fclk; | 1048 | struct samsung_fixed_rate_clock fclk; |
914 | struct clk *clk; | 1049 | struct clk *clk; |
915 | unsigned long finpll_f = 24000000; | 1050 | unsigned long finpll_f = 24000000; |
916 | char *parent_name; | 1051 | char *parent_name; |
1052 | unsigned int xom = exynos4_get_xom(); | ||
917 | 1053 | ||
918 | parent_name = xom & 1 ? "xusbxti" : "xxti"; | 1054 | parent_name = xom & 1 ? "xusbxti" : "xxti"; |
919 | clk = clk_get(NULL, parent_name); | 1055 | clk = clk_get(NULL, parent_name); |
@@ -1038,27 +1174,21 @@ static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = { | |||
1038 | 1174 | ||
1039 | /* register exynos4 clocks */ | 1175 | /* register exynos4 clocks */ |
1040 | static void __init exynos4_clk_init(struct device_node *np, | 1176 | static void __init exynos4_clk_init(struct device_node *np, |
1041 | enum exynos4_soc exynos4_soc, | 1177 | enum exynos4_soc soc) |
1042 | void __iomem *reg_base, unsigned long xom) | ||
1043 | { | 1178 | { |
1179 | exynos4_soc = soc; | ||
1180 | |||
1044 | reg_base = of_iomap(np, 0); | 1181 | reg_base = of_iomap(np, 0); |
1045 | if (!reg_base) | 1182 | if (!reg_base) |
1046 | panic("%s: failed to map registers\n", __func__); | 1183 | panic("%s: failed to map registers\n", __func__); |
1047 | 1184 | ||
1048 | if (exynos4_soc == EXYNOS4210) | 1185 | samsung_clk_init(np, reg_base, CLK_NR_CLKS); |
1049 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, | ||
1050 | exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), | ||
1051 | exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save)); | ||
1052 | else | ||
1053 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, | ||
1054 | exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), | ||
1055 | exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); | ||
1056 | 1186 | ||
1057 | samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, | 1187 | samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, |
1058 | ARRAY_SIZE(exynos4_fixed_rate_ext_clks), | 1188 | ARRAY_SIZE(exynos4_fixed_rate_ext_clks), |
1059 | ext_clk_match); | 1189 | ext_clk_match); |
1060 | 1190 | ||
1061 | exynos4_clk_register_finpll(xom); | 1191 | exynos4_clk_register_finpll(); |
1062 | 1192 | ||
1063 | if (exynos4_soc == EXYNOS4210) { | 1193 | if (exynos4_soc == EXYNOS4210) { |
1064 | samsung_clk_register_mux(exynos4210_mux_early, | 1194 | samsung_clk_register_mux(exynos4210_mux_early, |
@@ -1125,6 +1255,8 @@ static void __init exynos4_clk_init(struct device_node *np, | |||
1125 | samsung_clk_register_alias(exynos4_aliases, | 1255 | samsung_clk_register_alias(exynos4_aliases, |
1126 | ARRAY_SIZE(exynos4_aliases)); | 1256 | ARRAY_SIZE(exynos4_aliases)); |
1127 | 1257 | ||
1258 | exynos4_clk_sleep_init(); | ||
1259 | |||
1128 | pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" | 1260 | pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" |
1129 | "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", | 1261 | "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", |
1130 | exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", | 1262 | exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", |
@@ -1136,12 +1268,12 @@ static void __init exynos4_clk_init(struct device_node *np, | |||
1136 | 1268 | ||
1137 | static void __init exynos4210_clk_init(struct device_node *np) | 1269 | static void __init exynos4210_clk_init(struct device_node *np) |
1138 | { | 1270 | { |
1139 | exynos4_clk_init(np, EXYNOS4210, NULL, exynos4_get_xom()); | 1271 | exynos4_clk_init(np, EXYNOS4210); |
1140 | } | 1272 | } |
1141 | CLK_OF_DECLARE(exynos4210_clk, "samsung,exynos4210-clock", exynos4210_clk_init); | 1273 | CLK_OF_DECLARE(exynos4210_clk, "samsung,exynos4210-clock", exynos4210_clk_init); |
1142 | 1274 | ||
1143 | static void __init exynos4412_clk_init(struct device_node *np) | 1275 | static void __init exynos4412_clk_init(struct device_node *np) |
1144 | { | 1276 | { |
1145 | exynos4_clk_init(np, EXYNOS4X12, NULL, exynos4_get_xom()); | 1277 | exynos4_clk_init(np, EXYNOS4X12); |
1146 | } | 1278 | } |
1147 | CLK_OF_DECLARE(exynos4412_clk, "samsung,exynos4412-clock", exynos4412_clk_init); | 1279 | CLK_OF_DECLARE(exynos4412_clk, "samsung,exynos4412-clock", exynos4412_clk_init); |
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index ff4beebe1f0b..e7ee4420da81 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/clk-provider.h> | 16 | #include <linux/clk-provider.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/syscore_ops.h> | ||
19 | 20 | ||
20 | #include "clk.h" | 21 | #include "clk.h" |
21 | 22 | ||
@@ -85,6 +86,11 @@ enum exynos5250_plls { | |||
85 | nr_plls /* number of PLLs */ | 86 | nr_plls /* number of PLLs */ |
86 | }; | 87 | }; |
87 | 88 | ||
89 | static void __iomem *reg_base; | ||
90 | |||
91 | #ifdef CONFIG_PM_SLEEP | ||
92 | static struct samsung_clk_reg_dump *exynos5250_save; | ||
93 | |||
88 | /* | 94 | /* |
89 | * list of controller registers to be saved and restored during a | 95 | * list of controller registers to be saved and restored during a |
90 | * suspend/resume cycle. | 96 | * suspend/resume cycle. |
@@ -137,6 +143,41 @@ static unsigned long exynos5250_clk_regs[] __initdata = { | |||
137 | GATE_IP_ACP, | 143 | GATE_IP_ACP, |
138 | }; | 144 | }; |
139 | 145 | ||
146 | static int exynos5250_clk_suspend(void) | ||
147 | { | ||
148 | samsung_clk_save(reg_base, exynos5250_save, | ||
149 | ARRAY_SIZE(exynos5250_clk_regs)); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static void exynos5250_clk_resume(void) | ||
155 | { | ||
156 | samsung_clk_restore(reg_base, exynos5250_save, | ||
157 | ARRAY_SIZE(exynos5250_clk_regs)); | ||
158 | } | ||
159 | |||
160 | static struct syscore_ops exynos5250_clk_syscore_ops = { | ||
161 | .suspend = exynos5250_clk_suspend, | ||
162 | .resume = exynos5250_clk_resume, | ||
163 | }; | ||
164 | |||
165 | static void exynos5250_clk_sleep_init(void) | ||
166 | { | ||
167 | exynos5250_save = samsung_clk_alloc_reg_dump(exynos5250_clk_regs, | ||
168 | ARRAY_SIZE(exynos5250_clk_regs)); | ||
169 | if (!exynos5250_save) { | ||
170 | pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", | ||
171 | __func__); | ||
172 | return; | ||
173 | } | ||
174 | |||
175 | register_syscore_ops(&exynos5250_clk_syscore_ops); | ||
176 | } | ||
177 | #else | ||
178 | static void exynos5250_clk_sleep_init(void) {} | ||
179 | #endif | ||
180 | |||
140 | /* list of all parent clock list */ | 181 | /* list of all parent clock list */ |
141 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; | 182 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; |
142 | PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; | 183 | PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; |
@@ -645,8 +686,6 @@ static struct of_device_id ext_clk_match[] __initdata = { | |||
645 | /* register exynox5250 clocks */ | 686 | /* register exynox5250 clocks */ |
646 | static void __init exynos5250_clk_init(struct device_node *np) | 687 | static void __init exynos5250_clk_init(struct device_node *np) |
647 | { | 688 | { |
648 | void __iomem *reg_base; | ||
649 | |||
650 | if (np) { | 689 | if (np) { |
651 | reg_base = of_iomap(np, 0); | 690 | reg_base = of_iomap(np, 0); |
652 | if (!reg_base) | 691 | if (!reg_base) |
@@ -655,9 +694,7 @@ static void __init exynos5250_clk_init(struct device_node *np) | |||
655 | panic("%s: unable to determine soc\n", __func__); | 694 | panic("%s: unable to determine soc\n", __func__); |
656 | } | 695 | } |
657 | 696 | ||
658 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, | 697 | samsung_clk_init(np, reg_base, CLK_NR_CLKS); |
659 | exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs), | ||
660 | NULL, 0); | ||
661 | samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, | 698 | samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, |
662 | ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), | 699 | ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), |
663 | ext_clk_match); | 700 | ext_clk_match); |
@@ -685,6 +722,8 @@ static void __init exynos5250_clk_init(struct device_node *np) | |||
685 | samsung_clk_register_gate(exynos5250_gate_clks, | 722 | samsung_clk_register_gate(exynos5250_gate_clks, |
686 | ARRAY_SIZE(exynos5250_gate_clks)); | 723 | ARRAY_SIZE(exynos5250_gate_clks)); |
687 | 724 | ||
725 | exynos5250_clk_sleep_init(); | ||
726 | |||
688 | pr_info("Exynos5250: clock setup completed, armclk=%ld\n", | 727 | pr_info("Exynos5250: clock setup completed, armclk=%ld\n", |
689 | _get_rate("div_arm2")); | 728 | _get_rate("div_arm2")); |
690 | } | 729 | } |
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index ab4f2f7d88ef..60b26819bed5 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/clk-provider.h> | 16 | #include <linux/clk-provider.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/syscore_ops.h> | ||
19 | 20 | ||
20 | #include "clk.h" | 21 | #include "clk.h" |
21 | 22 | ||
@@ -108,6 +109,11 @@ enum exynos5420_plls { | |||
108 | nr_plls /* number of PLLs */ | 109 | nr_plls /* number of PLLs */ |
109 | }; | 110 | }; |
110 | 111 | ||
112 | static void __iomem *reg_base; | ||
113 | |||
114 | #ifdef CONFIG_PM_SLEEP | ||
115 | static struct samsung_clk_reg_dump *exynos5420_save; | ||
116 | |||
111 | /* | 117 | /* |
112 | * list of controller registers to be saved and restored during a | 118 | * list of controller registers to be saved and restored during a |
113 | * suspend/resume cycle. | 119 | * suspend/resume cycle. |
@@ -174,6 +180,41 @@ static unsigned long exynos5420_clk_regs[] __initdata = { | |||
174 | DIV_KFC0, | 180 | DIV_KFC0, |
175 | }; | 181 | }; |
176 | 182 | ||
183 | static int exynos5420_clk_suspend(void) | ||
184 | { | ||
185 | samsung_clk_save(reg_base, exynos5420_save, | ||
186 | ARRAY_SIZE(exynos5420_clk_regs)); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static void exynos5420_clk_resume(void) | ||
192 | { | ||
193 | samsung_clk_restore(reg_base, exynos5420_save, | ||
194 | ARRAY_SIZE(exynos5420_clk_regs)); | ||
195 | } | ||
196 | |||
197 | static struct syscore_ops exynos5420_clk_syscore_ops = { | ||
198 | .suspend = exynos5420_clk_suspend, | ||
199 | .resume = exynos5420_clk_resume, | ||
200 | }; | ||
201 | |||
202 | static void exynos5420_clk_sleep_init(void) | ||
203 | { | ||
204 | exynos5420_save = samsung_clk_alloc_reg_dump(exynos5420_clk_regs, | ||
205 | ARRAY_SIZE(exynos5420_clk_regs)); | ||
206 | if (!exynos5420_save) { | ||
207 | pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", | ||
208 | __func__); | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | register_syscore_ops(&exynos5420_clk_syscore_ops); | ||
213 | } | ||
214 | #else | ||
215 | static void exynos5420_clk_sleep_init(void) {} | ||
216 | #endif | ||
217 | |||
177 | /* list of all parent clocks */ | 218 | /* list of all parent clocks */ |
178 | PNAME(mspll_cpu_p) = { "sclk_cpll", "sclk_dpll", | 219 | PNAME(mspll_cpu_p) = { "sclk_cpll", "sclk_dpll", |
179 | "sclk_mpll", "sclk_spll" }; | 220 | "sclk_mpll", "sclk_spll" }; |
@@ -737,8 +778,6 @@ static struct of_device_id ext_clk_match[] __initdata = { | |||
737 | /* register exynos5420 clocks */ | 778 | /* register exynos5420 clocks */ |
738 | static void __init exynos5420_clk_init(struct device_node *np) | 779 | static void __init exynos5420_clk_init(struct device_node *np) |
739 | { | 780 | { |
740 | void __iomem *reg_base; | ||
741 | |||
742 | if (np) { | 781 | if (np) { |
743 | reg_base = of_iomap(np, 0); | 782 | reg_base = of_iomap(np, 0); |
744 | if (!reg_base) | 783 | if (!reg_base) |
@@ -747,9 +786,7 @@ static void __init exynos5420_clk_init(struct device_node *np) | |||
747 | panic("%s: unable to determine soc\n", __func__); | 786 | panic("%s: unable to determine soc\n", __func__); |
748 | } | 787 | } |
749 | 788 | ||
750 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, | 789 | samsung_clk_init(np, reg_base, CLK_NR_CLKS); |
751 | exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs), | ||
752 | NULL, 0); | ||
753 | samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks, | 790 | samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks, |
754 | ARRAY_SIZE(exynos5420_fixed_rate_ext_clks), | 791 | ARRAY_SIZE(exynos5420_fixed_rate_ext_clks), |
755 | ext_clk_match); | 792 | ext_clk_match); |
@@ -765,5 +802,7 @@ static void __init exynos5420_clk_init(struct device_node *np) | |||
765 | ARRAY_SIZE(exynos5420_div_clks)); | 802 | ARRAY_SIZE(exynos5420_div_clks)); |
766 | samsung_clk_register_gate(exynos5420_gate_clks, | 803 | samsung_clk_register_gate(exynos5420_gate_clks, |
767 | ARRAY_SIZE(exynos5420_gate_clks)); | 804 | ARRAY_SIZE(exynos5420_gate_clks)); |
805 | |||
806 | exynos5420_clk_sleep_init(); | ||
768 | } | 807 | } |
769 | CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init); | 808 | CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init); |
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index cbc15b56891d..2bfad5a993d0 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c | |||
@@ -101,7 +101,7 @@ static void __init exynos5440_clk_init(struct device_node *np) | |||
101 | return; | 101 | return; |
102 | } | 102 | } |
103 | 103 | ||
104 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); | 104 | samsung_clk_init(np, reg_base, CLK_NR_CLKS); |
105 | samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, | 105 | samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, |
106 | ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); | 106 | ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); |
107 | 107 | ||
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 8e27aee6887e..8bda658137a8 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
16 | #include <linux/syscore_ops.h> | ||
16 | 17 | ||
17 | #include <dt-bindings/clock/samsung,s3c64xx-clock.h> | 18 | #include <dt-bindings/clock/samsung,s3c64xx-clock.h> |
18 | 19 | ||
@@ -61,6 +62,13 @@ enum s3c64xx_plls { | |||
61 | apll, mpll, epll, | 62 | apll, mpll, epll, |
62 | }; | 63 | }; |
63 | 64 | ||
65 | static void __iomem *reg_base; | ||
66 | static bool is_s3c6400; | ||
67 | |||
68 | #ifdef CONFIG_PM_SLEEP | ||
69 | static struct samsung_clk_reg_dump *s3c64xx_save_common; | ||
70 | static struct samsung_clk_reg_dump *s3c64xx_save_soc; | ||
71 | |||
64 | /* | 72 | /* |
65 | * List of controller registers to be saved and restored during | 73 | * List of controller registers to be saved and restored during |
66 | * a suspend/resume cycle. | 74 | * a suspend/resume cycle. |
@@ -87,6 +95,60 @@ static unsigned long s3c6410_clk_regs[] __initdata = { | |||
87 | MEM0_GATE, | 95 | MEM0_GATE, |
88 | }; | 96 | }; |
89 | 97 | ||
98 | static int s3c64xx_clk_suspend(void) | ||
99 | { | ||
100 | samsung_clk_save(reg_base, s3c64xx_save_common, | ||
101 | ARRAY_SIZE(s3c64xx_clk_regs)); | ||
102 | |||
103 | if (!is_s3c6400) | ||
104 | samsung_clk_save(reg_base, s3c64xx_save_soc, | ||
105 | ARRAY_SIZE(s3c6410_clk_regs)); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void s3c64xx_clk_resume(void) | ||
111 | { | ||
112 | samsung_clk_restore(reg_base, s3c64xx_save_common, | ||
113 | ARRAY_SIZE(s3c64xx_clk_regs)); | ||
114 | |||
115 | if (!is_s3c6400) | ||
116 | samsung_clk_restore(reg_base, s3c64xx_save_soc, | ||
117 | ARRAY_SIZE(s3c6410_clk_regs)); | ||
118 | } | ||
119 | |||
120 | static struct syscore_ops s3c64xx_clk_syscore_ops = { | ||
121 | .suspend = s3c64xx_clk_suspend, | ||
122 | .resume = s3c64xx_clk_resume, | ||
123 | }; | ||
124 | |||
125 | static void s3c64xx_clk_sleep_init(void) | ||
126 | { | ||
127 | s3c64xx_save_common = samsung_clk_alloc_reg_dump(s3c64xx_clk_regs, | ||
128 | ARRAY_SIZE(s3c64xx_clk_regs)); | ||
129 | if (!s3c64xx_save_common) | ||
130 | goto err_warn; | ||
131 | |||
132 | if (!is_s3c6400) { | ||
133 | s3c64xx_save_soc = samsung_clk_alloc_reg_dump(s3c6410_clk_regs, | ||
134 | ARRAY_SIZE(s3c6410_clk_regs)); | ||
135 | if (!s3c64xx_save_soc) | ||
136 | goto err_soc; | ||
137 | } | ||
138 | |||
139 | register_syscore_ops(&s3c64xx_clk_syscore_ops); | ||
140 | return; | ||
141 | |||
142 | err_soc: | ||
143 | kfree(s3c64xx_save_common); | ||
144 | err_warn: | ||
145 | pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", | ||
146 | __func__); | ||
147 | } | ||
148 | #else | ||
149 | static void s3c64xx_clk_sleep_init(void) {} | ||
150 | #endif | ||
151 | |||
90 | /* List of parent clocks common for all S3C64xx SoCs. */ | 152 | /* List of parent clocks common for all S3C64xx SoCs. */ |
91 | PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" }; | 153 | PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" }; |
92 | PNAME(uart_p) = { "mout_epll", "dout_mpll" }; | 154 | PNAME(uart_p) = { "mout_epll", "dout_mpll" }; |
@@ -391,11 +453,11 @@ static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f, | |||
391 | 453 | ||
392 | /* Register s3c64xx clocks. */ | 454 | /* Register s3c64xx clocks. */ |
393 | void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, | 455 | void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, |
394 | unsigned long xusbxti_f, bool is_s3c6400, | 456 | unsigned long xusbxti_f, bool s3c6400, |
395 | void __iomem *reg_base) | 457 | void __iomem *base) |
396 | { | 458 | { |
397 | unsigned long *soc_regs = NULL; | 459 | reg_base = base; |
398 | unsigned long nr_soc_regs = 0; | 460 | is_s3c6400 = s3c6400; |
399 | 461 | ||
400 | if (np) { | 462 | if (np) { |
401 | reg_base = of_iomap(np, 0); | 463 | reg_base = of_iomap(np, 0); |
@@ -403,13 +465,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, | |||
403 | panic("%s: failed to map registers\n", __func__); | 465 | panic("%s: failed to map registers\n", __func__); |
404 | } | 466 | } |
405 | 467 | ||
406 | if (!is_s3c6400) { | 468 | samsung_clk_init(np, reg_base, NR_CLKS); |
407 | soc_regs = s3c6410_clk_regs; | ||
408 | nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs); | ||
409 | } | ||
410 | |||
411 | samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs, | ||
412 | ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs); | ||
413 | 469 | ||
414 | /* Register external clocks. */ | 470 | /* Register external clocks. */ |
415 | if (!np) | 471 | if (!np) |
@@ -452,6 +508,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, | |||
452 | 508 | ||
453 | samsung_clk_register_alias(s3c64xx_clock_aliases, | 509 | samsung_clk_register_alias(s3c64xx_clock_aliases, |
454 | ARRAY_SIZE(s3c64xx_clock_aliases)); | 510 | ARRAY_SIZE(s3c64xx_clock_aliases)); |
511 | s3c64xx_clk_sleep_init(); | ||
455 | 512 | ||
456 | pr_info("%s clocks: apll = %lu, mpll = %lu\n" | 513 | pr_info("%s clocks: apll = %lu, mpll = %lu\n" |
457 | "\tepll = %lu, arm_clk = %lu\n", | 514 | "\tepll = %lu, arm_clk = %lu\n", |
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index f503f32e2f80..91bec3ebdc8f 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c | |||
@@ -21,64 +21,45 @@ static void __iomem *reg_base; | |||
21 | static struct clk_onecell_data clk_data; | 21 | static struct clk_onecell_data clk_data; |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #ifdef CONFIG_PM_SLEEP | 24 | void samsung_clk_save(void __iomem *base, |
25 | static struct samsung_clk_reg_dump *reg_dump; | 25 | struct samsung_clk_reg_dump *rd, |
26 | static unsigned long nr_reg_dump; | 26 | unsigned int num_regs) |
27 | |||
28 | static int samsung_clk_suspend(void) | ||
29 | { | 27 | { |
30 | struct samsung_clk_reg_dump *rd = reg_dump; | 28 | for (; num_regs > 0; --num_regs, ++rd) |
31 | unsigned long i; | 29 | rd->value = readl(base + rd->offset); |
32 | 30 | } | |
33 | for (i = 0; i < nr_reg_dump; i++, rd++) | ||
34 | rd->value = __raw_readl(reg_base + rd->offset); | ||
35 | 31 | ||
36 | return 0; | 32 | void samsung_clk_restore(void __iomem *base, |
33 | const struct samsung_clk_reg_dump *rd, | ||
34 | unsigned int num_regs) | ||
35 | { | ||
36 | for (; num_regs > 0; --num_regs, ++rd) | ||
37 | writel(rd->value, base + rd->offset); | ||
37 | } | 38 | } |
38 | 39 | ||
39 | static void samsung_clk_resume(void) | 40 | struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( |
41 | const unsigned long *rdump, | ||
42 | unsigned long nr_rdump) | ||
40 | { | 43 | { |
41 | struct samsung_clk_reg_dump *rd = reg_dump; | 44 | struct samsung_clk_reg_dump *rd; |
42 | unsigned long i; | 45 | unsigned int i; |
43 | 46 | ||
44 | for (i = 0; i < nr_reg_dump; i++, rd++) | 47 | rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL); |
45 | __raw_writel(rd->value, reg_base + rd->offset); | 48 | if (!rd) |
46 | } | 49 | return NULL; |
50 | |||
51 | for (i = 0; i < nr_rdump; ++i) | ||
52 | rd[i].offset = rdump[i]; | ||
47 | 53 | ||
48 | static struct syscore_ops samsung_clk_syscore_ops = { | 54 | return rd; |
49 | .suspend = samsung_clk_suspend, | 55 | } |
50 | .resume = samsung_clk_resume, | ||
51 | }; | ||
52 | #endif /* CONFIG_PM_SLEEP */ | ||
53 | 56 | ||
54 | /* setup the essentials required to support clock lookup using ccf */ | 57 | /* setup the essentials required to support clock lookup using ccf */ |
55 | void __init samsung_clk_init(struct device_node *np, void __iomem *base, | 58 | void __init samsung_clk_init(struct device_node *np, void __iomem *base, |
56 | unsigned long nr_clks, unsigned long *rdump, | 59 | unsigned long nr_clks) |
57 | unsigned long nr_rdump, unsigned long *soc_rdump, | ||
58 | unsigned long nr_soc_rdump) | ||
59 | { | 60 | { |
60 | reg_base = base; | 61 | reg_base = base; |
61 | 62 | ||
62 | #ifdef CONFIG_PM_SLEEP | ||
63 | if (rdump && nr_rdump) { | ||
64 | unsigned int idx; | ||
65 | reg_dump = kzalloc(sizeof(struct samsung_clk_reg_dump) | ||
66 | * (nr_rdump + nr_soc_rdump), GFP_KERNEL); | ||
67 | if (!reg_dump) { | ||
68 | pr_err("%s: memory alloc for register dump failed\n", | ||
69 | __func__); | ||
70 | return; | ||
71 | } | ||
72 | |||
73 | for (idx = 0; idx < nr_rdump; idx++) | ||
74 | reg_dump[idx].offset = rdump[idx]; | ||
75 | for (idx = 0; idx < nr_soc_rdump; idx++) | ||
76 | reg_dump[nr_rdump + idx].offset = soc_rdump[idx]; | ||
77 | nr_reg_dump = nr_rdump + nr_soc_rdump; | ||
78 | register_syscore_ops(&samsung_clk_syscore_ops); | ||
79 | } | ||
80 | #endif | ||
81 | |||
82 | clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); | 63 | clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); |
83 | if (!clk_table) | 64 | if (!clk_table) |
84 | panic("could not allocate clock lookup table\n"); | 65 | panic("could not allocate clock lookup table\n"); |
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 31b4174e7a5b..c7141ba826e0 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h | |||
@@ -313,9 +313,7 @@ struct samsung_pll_clock { | |||
313 | _lock, _con, _rtable, _alias) | 313 | _lock, _con, _rtable, _alias) |
314 | 314 | ||
315 | extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, | 315 | extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, |
316 | unsigned long nr_clks, unsigned long *rdump, | 316 | unsigned long nr_clks); |
317 | unsigned long nr_rdump, unsigned long *soc_rdump, | ||
318 | unsigned long nr_soc_rdump); | ||
319 | extern void __init samsung_clk_of_register_fixed_ext( | 317 | extern void __init samsung_clk_of_register_fixed_ext( |
320 | struct samsung_fixed_rate_clock *fixed_rate_clk, | 318 | struct samsung_fixed_rate_clock *fixed_rate_clk, |
321 | unsigned int nr_fixed_rate_clk, | 319 | unsigned int nr_fixed_rate_clk, |
@@ -340,4 +338,14 @@ extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, | |||
340 | 338 | ||
341 | extern unsigned long _get_rate(const char *clk_name); | 339 | extern unsigned long _get_rate(const char *clk_name); |
342 | 340 | ||
341 | extern void samsung_clk_save(void __iomem *base, | ||
342 | struct samsung_clk_reg_dump *rd, | ||
343 | unsigned int num_regs); | ||
344 | extern void samsung_clk_restore(void __iomem *base, | ||
345 | const struct samsung_clk_reg_dump *rd, | ||
346 | unsigned int num_regs); | ||
347 | extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( | ||
348 | const unsigned long *rdump, | ||
349 | unsigned long nr_rdump); | ||
350 | |||
343 | #endif /* __SAMSUNG_CLK_H */ | 351 | #endif /* __SAMSUNG_CLK_H */ |
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 8cbfcf88fae3..a820b0cfcf57 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c | |||
@@ -33,7 +33,7 @@ struct clk_icst { | |||
33 | struct clk_hw hw; | 33 | struct clk_hw hw; |
34 | void __iomem *vcoreg; | 34 | void __iomem *vcoreg; |
35 | void __iomem *lockreg; | 35 | void __iomem *lockreg; |
36 | const struct icst_params *params; | 36 | struct icst_params *params; |
37 | unsigned long rate; | 37 | unsigned long rate; |
38 | }; | 38 | }; |
39 | 39 | ||
@@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw, | |||
84 | struct clk_icst *icst = to_icst(hw); | 84 | struct clk_icst *icst = to_icst(hw); |
85 | struct icst_vco vco; | 85 | struct icst_vco vco; |
86 | 86 | ||
87 | if (parent_rate) | ||
88 | icst->params->ref = parent_rate; | ||
87 | vco = vco_get(icst->vcoreg); | 89 | vco = vco_get(icst->vcoreg); |
88 | icst->rate = icst_hz(icst->params, vco); | 90 | icst->rate = icst_hz(icst->params, vco); |
89 | return icst->rate; | 91 | return icst->rate; |
@@ -105,6 +107,8 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate, | |||
105 | struct clk_icst *icst = to_icst(hw); | 107 | struct clk_icst *icst = to_icst(hw); |
106 | struct icst_vco vco; | 108 | struct icst_vco vco; |
107 | 109 | ||
110 | if (parent_rate) | ||
111 | icst->params->ref = parent_rate; | ||
108 | vco = icst_hz_to_vco(icst->params, rate); | 112 | vco = icst_hz_to_vco(icst->params, rate); |
109 | icst->rate = icst_hz(icst->params, vco); | 113 | icst->rate = icst_hz(icst->params, vco); |
110 | vco_set(icst->lockreg, icst->vcoreg, vco); | 114 | vco_set(icst->lockreg, icst->vcoreg, vco); |
@@ -120,24 +124,33 @@ static const struct clk_ops icst_ops = { | |||
120 | struct clk *icst_clk_register(struct device *dev, | 124 | struct clk *icst_clk_register(struct device *dev, |
121 | const struct clk_icst_desc *desc, | 125 | const struct clk_icst_desc *desc, |
122 | const char *name, | 126 | const char *name, |
127 | const char *parent_name, | ||
123 | void __iomem *base) | 128 | void __iomem *base) |
124 | { | 129 | { |
125 | struct clk *clk; | 130 | struct clk *clk; |
126 | struct clk_icst *icst; | 131 | struct clk_icst *icst; |
127 | struct clk_init_data init; | 132 | struct clk_init_data init; |
133 | struct icst_params *pclone; | ||
128 | 134 | ||
129 | icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL); | 135 | icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL); |
130 | if (!icst) { | 136 | if (!icst) { |
131 | pr_err("could not allocate ICST clock!\n"); | 137 | pr_err("could not allocate ICST clock!\n"); |
132 | return ERR_PTR(-ENOMEM); | 138 | return ERR_PTR(-ENOMEM); |
133 | } | 139 | } |
140 | |||
141 | pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL); | ||
142 | if (!pclone) { | ||
143 | pr_err("could not clone ICST params\n"); | ||
144 | return ERR_PTR(-ENOMEM); | ||
145 | } | ||
146 | |||
134 | init.name = name; | 147 | init.name = name; |
135 | init.ops = &icst_ops; | 148 | init.ops = &icst_ops; |
136 | init.flags = CLK_IS_ROOT; | 149 | init.flags = CLK_IS_ROOT; |
137 | init.parent_names = NULL; | 150 | init.parent_names = (parent_name ? &parent_name : NULL); |
138 | init.num_parents = 0; | 151 | init.num_parents = (parent_name ? 1 : 0); |
139 | icst->hw.init = &init; | 152 | icst->hw.init = &init; |
140 | icst->params = desc->params; | 153 | icst->params = pclone; |
141 | icst->vcoreg = base + desc->vco_offset; | 154 | icst->vcoreg = base + desc->vco_offset; |
142 | icst->lockreg = base + desc->lock_offset; | 155 | icst->lockreg = base + desc->lock_offset; |
143 | 156 | ||
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h index be99dd0da785..04e6f0aef588 100644 --- a/drivers/clk/versatile/clk-icst.h +++ b/drivers/clk/versatile/clk-icst.h | |||
@@ -16,4 +16,5 @@ struct clk_icst_desc { | |||
16 | struct clk *icst_clk_register(struct device *dev, | 16 | struct clk *icst_clk_register(struct device *dev, |
17 | const struct clk_icst_desc *desc, | 17 | const struct clk_icst_desc *desc, |
18 | const char *name, | 18 | const char *name, |
19 | const char *parent_name, | ||
19 | void __iomem *base); | 20 | void __iomem *base); |
diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 844f8d711a12..6d8b8e1a080a 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c | |||
@@ -93,13 +93,15 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id) | |||
93 | imc = &impd1_clks[id]; | 93 | imc = &impd1_clks[id]; |
94 | 94 | ||
95 | imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); | 95 | imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); |
96 | clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, base); | 96 | clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, NULL, |
97 | base); | ||
97 | imc->vco1clk = clk; | 98 | imc->vco1clk = clk; |
98 | imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); | 99 | imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); |
99 | 100 | ||
100 | /* VCO2 is also called "CLK2" */ | 101 | /* VCO2 is also called "CLK2" */ |
101 | imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id); | 102 | imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id); |
102 | clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, base); | 103 | clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, NULL, |
104 | base); | ||
103 | imc->vco2clk = clk; | 105 | imc->vco2clk = clk; |
104 | 106 | ||
105 | /* MMCI uses CLK2 right off */ | 107 | /* MMCI uses CLK2 right off */ |
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c index bda8967e09c2..734c4b8fe6ab 100644 --- a/drivers/clk/versatile/clk-integrator.c +++ b/drivers/clk/versatile/clk-integrator.c | |||
@@ -10,21 +10,17 @@ | |||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/clkdev.h> | 11 | #include <linux/clkdev.h> |
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/platform_data/clk-integrator.h> | 13 | #include <linux/of.h> |
14 | 14 | #include <linux/of_address.h> | |
15 | #include <mach/hardware.h> | ||
16 | #include <mach/platform.h> | ||
17 | 15 | ||
18 | #include "clk-icst.h" | 16 | #include "clk-icst.h" |
19 | 17 | ||
20 | /* | 18 | #define INTEGRATOR_HDR_LOCK_OFFSET 0x14 |
21 | * Implementation of the ARM Integrator/AP and Integrator/CP clock tree. | ||
22 | * Inspired by portions of: | ||
23 | * plat-versatile/clock.c and plat-versatile/include/plat/clock.h | ||
24 | */ | ||
25 | 19 | ||
26 | static const struct icst_params cp_auxvco_params = { | 20 | /* Base offset for the core module */ |
27 | .ref = 24000000, | 21 | static void __iomem *cm_base; |
22 | |||
23 | static const struct icst_params cp_auxosc_params = { | ||
28 | .vco_max = ICST525_VCO_MAX_5V, | 24 | .vco_max = ICST525_VCO_MAX_5V, |
29 | .vco_min = ICST525_VCO_MIN, | 25 | .vco_min = ICST525_VCO_MIN, |
30 | .vd_min = 8, | 26 | .vd_min = 8, |
@@ -35,50 +31,39 @@ static const struct icst_params cp_auxvco_params = { | |||
35 | .idx2s = icst525_idx2s, | 31 | .idx2s = icst525_idx2s, |
36 | }; | 32 | }; |
37 | 33 | ||
38 | static const struct clk_icst_desc __initdata cp_icst_desc = { | 34 | static const struct clk_icst_desc __initdata cm_auxosc_desc = { |
39 | .params = &cp_auxvco_params, | 35 | .params = &cp_auxosc_params, |
40 | .vco_offset = 0x1c, | 36 | .vco_offset = 0x1c, |
41 | .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, | 37 | .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, |
42 | }; | 38 | }; |
43 | 39 | ||
44 | /* | 40 | static void __init of_integrator_cm_osc_setup(struct device_node *np) |
45 | * integrator_clk_init() - set up the integrator clock tree | ||
46 | * @is_cp: pass true if it's the Integrator/CP else AP is assumed | ||
47 | */ | ||
48 | void __init integrator_clk_init(bool is_cp) | ||
49 | { | 41 | { |
50 | struct clk *clk; | 42 | struct clk *clk = ERR_PTR(-EINVAL); |
51 | 43 | const char *clk_name = np->name; | |
52 | /* APB clock dummy */ | 44 | const struct clk_icst_desc *desc = &cm_auxosc_desc; |
53 | clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); | 45 | const char *parent_name; |
54 | clk_register_clkdev(clk, "apb_pclk", NULL); | ||
55 | |||
56 | /* UART reference clock */ | ||
57 | clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, | ||
58 | 14745600); | ||
59 | clk_register_clkdev(clk, NULL, "uart0"); | ||
60 | clk_register_clkdev(clk, NULL, "uart1"); | ||
61 | if (is_cp) | ||
62 | clk_register_clkdev(clk, NULL, "mmci"); | ||
63 | |||
64 | /* 24 MHz clock */ | ||
65 | clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, | ||
66 | 24000000); | ||
67 | clk_register_clkdev(clk, NULL, "kmi0"); | ||
68 | clk_register_clkdev(clk, NULL, "kmi1"); | ||
69 | if (!is_cp) | ||
70 | clk_register_clkdev(clk, NULL, "ap_timer"); | ||
71 | 46 | ||
72 | if (!is_cp) | 47 | if (!cm_base) { |
73 | return; | 48 | /* Remap the core module base if not done yet */ |
49 | struct device_node *parent; | ||
74 | 50 | ||
75 | /* 1 MHz clock */ | 51 | parent = of_get_parent(np); |
76 | clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, | 52 | if (!np) { |
77 | 1000000); | 53 | pr_err("no parent on core module clock\n"); |
78 | clk_register_clkdev(clk, NULL, "sp804"); | 54 | return; |
55 | } | ||
56 | cm_base = of_iomap(parent, 0); | ||
57 | if (!cm_base) { | ||
58 | pr_err("could not remap core module base\n"); | ||
59 | return; | ||
60 | } | ||
61 | } | ||
79 | 62 | ||
80 | /* ICST VCO clock used on the Integrator/CP CLCD */ | 63 | parent_name = of_clk_get_parent_name(np, 0); |
81 | clk = icst_clk_register(NULL, &cp_icst_desc, "icst", | 64 | clk = icst_clk_register(NULL, desc, clk_name, parent_name, cm_base); |
82 | __io_address(INTEGRATOR_HDR_BASE)); | 65 | if (!IS_ERR(clk)) |
83 | clk_register_clkdev(clk, NULL, "clcd"); | 66 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
84 | } | 67 | } |
68 | CLK_OF_DECLARE(integrator_cm_auxosc_clk, | ||
69 | "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup); | ||
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c index 747e7b31117c..c8b523117fb7 100644 --- a/drivers/clk/versatile/clk-realview.c +++ b/drivers/clk/versatile/clk-realview.c | |||
@@ -85,10 +85,10 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) | |||
85 | /* ICST VCO clock */ | 85 | /* ICST VCO clock */ |
86 | if (is_pb1176) | 86 | if (is_pb1176) |
87 | clk = icst_clk_register(NULL, &realview_osc0_desc, | 87 | clk = icst_clk_register(NULL, &realview_osc0_desc, |
88 | "osc0", sysbase); | 88 | "osc0", NULL, sysbase); |
89 | else | 89 | else |
90 | clk = icst_clk_register(NULL, &realview_osc4_desc, | 90 | clk = icst_clk_register(NULL, &realview_osc4_desc, |
91 | "osc4", sysbase); | 91 | "osc4", NULL, sysbase); |
92 | 92 | ||
93 | clk_register_clkdev(clk, NULL, "dev:clcd"); | 93 | clk_register_clkdev(clk, NULL, "dev:clcd"); |
94 | clk_register_clkdev(clk, NULL, "issp:clcd"); | 94 | clk_register_clkdev(clk, NULL, "issp:clcd"); |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 9fb627046e17..1e2b9db563ec 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -122,7 +122,7 @@ config ARM_INTEGRATOR | |||
122 | If in doubt, say Y. | 122 | If in doubt, say Y. |
123 | 123 | ||
124 | config ARM_KIRKWOOD_CPUFREQ | 124 | config ARM_KIRKWOOD_CPUFREQ |
125 | def_bool ARCH_KIRKWOOD && OF | 125 | def_bool MACH_KIRKWOOD |
126 | help | 126 | help |
127 | This adds the CPUFreq driver for Marvell Kirkwood | 127 | This adds the CPUFreq driver for Marvell Kirkwood |
128 | SoCs. | 128 | SoCs. |
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index d988948a89a0..97ccc31dbdd8 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm | |||
@@ -22,7 +22,7 @@ config ARM_HIGHBANK_CPUIDLE | |||
22 | 22 | ||
23 | config ARM_KIRKWOOD_CPUIDLE | 23 | config ARM_KIRKWOOD_CPUIDLE |
24 | bool "CPU Idle Driver for Marvell Kirkwood SoCs" | 24 | bool "CPU Idle Driver for Marvell Kirkwood SoCs" |
25 | depends on ARCH_KIRKWOOD | 25 | depends on ARCH_KIRKWOOD || MACH_KIRKWOOD |
26 | help | 26 | help |
27 | This adds the CPU Idle driver for Marvell Kirkwood SoCs. | 27 | This adds the CPU Idle driver for Marvell Kirkwood SoCs. |
28 | 28 | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 92d8e9a064b4..a86c49a605c6 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -210,7 +210,7 @@ config GPIO_MSM_V1 | |||
210 | 210 | ||
211 | config GPIO_MSM_V2 | 211 | config GPIO_MSM_V2 |
212 | tristate "Qualcomm MSM GPIO v2" | 212 | tristate "Qualcomm MSM GPIO v2" |
213 | depends on GPIOLIB && OF && ARCH_MSM | 213 | depends on GPIOLIB && OF && ARCH_QCOM |
214 | help | 214 | help |
215 | Say yes here to support the GPIO interface on ARM v7 based | 215 | Say yes here to support the GPIO interface on ARM v7 based |
216 | Qualcomm MSM chips. Most of the pins on the MSM can be | 216 | Qualcomm MSM chips. Most of the pins on the MSM can be |
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index c69d1e07a3a6..b6984971ce0c 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig | |||
@@ -3,7 +3,7 @@ config DRM_MSM | |||
3 | tristate "MSM DRM" | 3 | tristate "MSM DRM" |
4 | depends on DRM | 4 | depends on DRM |
5 | depends on MSM_IOMMU | 5 | depends on MSM_IOMMU |
6 | depends on (ARCH_MSM && ARCH_MSM8960) || (ARM && COMPILE_TEST) | 6 | depends on ARCH_MSM8960 || (ARM && COMPILE_TEST) |
7 | select DRM_KMS_HELPER | 7 | select DRM_KMS_HELPER |
8 | select SHMEM | 8 | select SHMEM |
9 | select TMPFS | 9 | select TMPFS |
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index ec42d2decb2f..d770f7406631 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
@@ -77,3 +77,11 @@ config VERSATILE_FPGA_IRQ_NR | |||
77 | config XTENSA_MX | 77 | config XTENSA_MX |
78 | bool | 78 | bool |
79 | select IRQ_DOMAIN | 79 | select IRQ_DOMAIN |
80 | |||
81 | config IRQ_CROSSBAR | ||
82 | bool | ||
83 | help | ||
84 | Support for a CROSSBAR ip that preceeds the main interrupt controller. | ||
85 | The primary irqchip invokes the crossbar's callback which inturn allocates | ||
86 | a free irq and configures the IP. Thus the peripheral interrupts are | ||
87 | routed to one of the free irqchip interrupt lines. | ||
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 6cee9efa26e7..f180f8d5fb7b 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -28,3 +28,4 @@ obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o | |||
28 | obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o | 28 | obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o |
29 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o | 29 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o |
30 | obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o | 30 | obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o |
31 | obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o | ||
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c new file mode 100644 index 000000000000..fc817d28d1fe --- /dev/null +++ b/drivers/irqchip/irq-crossbar.c | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * drivers/irqchip/irq-crossbar.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * Author: Sricharan R <r.sricharan@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/of_address.h> | ||
15 | #include <linux/of_irq.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/irqchip/arm-gic.h> | ||
18 | |||
19 | #define IRQ_FREE -1 | ||
20 | #define GIC_IRQ_START 32 | ||
21 | |||
22 | /* | ||
23 | * @int_max: maximum number of supported interrupts | ||
24 | * @irq_map: array of interrupts to crossbar number mapping | ||
25 | * @crossbar_base: crossbar base address | ||
26 | * @register_offsets: offsets for each irq number | ||
27 | */ | ||
28 | struct crossbar_device { | ||
29 | uint int_max; | ||
30 | uint *irq_map; | ||
31 | void __iomem *crossbar_base; | ||
32 | int *register_offsets; | ||
33 | void (*write) (int, int); | ||
34 | }; | ||
35 | |||
36 | static struct crossbar_device *cb; | ||
37 | |||
38 | static inline void crossbar_writel(int irq_no, int cb_no) | ||
39 | { | ||
40 | writel(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]); | ||
41 | } | ||
42 | |||
43 | static inline void crossbar_writew(int irq_no, int cb_no) | ||
44 | { | ||
45 | writew(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]); | ||
46 | } | ||
47 | |||
48 | static inline void crossbar_writeb(int irq_no, int cb_no) | ||
49 | { | ||
50 | writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]); | ||
51 | } | ||
52 | |||
53 | static inline int allocate_free_irq(int cb_no) | ||
54 | { | ||
55 | int i; | ||
56 | |||
57 | for (i = 0; i < cb->int_max; i++) { | ||
58 | if (cb->irq_map[i] == IRQ_FREE) { | ||
59 | cb->irq_map[i] = cb_no; | ||
60 | return i; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | return -ENODEV; | ||
65 | } | ||
66 | |||
67 | static int crossbar_domain_map(struct irq_domain *d, unsigned int irq, | ||
68 | irq_hw_number_t hw) | ||
69 | { | ||
70 | cb->write(hw - GIC_IRQ_START, cb->irq_map[hw - GIC_IRQ_START]); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static void crossbar_domain_unmap(struct irq_domain *d, unsigned int irq) | ||
75 | { | ||
76 | irq_hw_number_t hw = irq_get_irq_data(irq)->hwirq; | ||
77 | |||
78 | if (hw > GIC_IRQ_START) | ||
79 | cb->irq_map[hw - GIC_IRQ_START] = IRQ_FREE; | ||
80 | } | ||
81 | |||
82 | static int crossbar_domain_xlate(struct irq_domain *d, | ||
83 | struct device_node *controller, | ||
84 | const u32 *intspec, unsigned int intsize, | ||
85 | unsigned long *out_hwirq, | ||
86 | unsigned int *out_type) | ||
87 | { | ||
88 | unsigned long ret; | ||
89 | |||
90 | ret = allocate_free_irq(intspec[1]); | ||
91 | |||
92 | if (IS_ERR_VALUE(ret)) | ||
93 | return ret; | ||
94 | |||
95 | *out_hwirq = ret + GIC_IRQ_START; | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | const struct irq_domain_ops routable_irq_domain_ops = { | ||
100 | .map = crossbar_domain_map, | ||
101 | .unmap = crossbar_domain_unmap, | ||
102 | .xlate = crossbar_domain_xlate | ||
103 | }; | ||
104 | |||
105 | static int __init crossbar_of_init(struct device_node *node) | ||
106 | { | ||
107 | int i, size, max, reserved = 0, entry; | ||
108 | const __be32 *irqsr; | ||
109 | |||
110 | cb = kzalloc(sizeof(struct cb_device *), GFP_KERNEL); | ||
111 | |||
112 | if (!cb) | ||
113 | return -ENOMEM; | ||
114 | |||
115 | cb->crossbar_base = of_iomap(node, 0); | ||
116 | if (!cb->crossbar_base) | ||
117 | goto err1; | ||
118 | |||
119 | of_property_read_u32(node, "ti,max-irqs", &max); | ||
120 | cb->irq_map = kzalloc(max * sizeof(int), GFP_KERNEL); | ||
121 | if (!cb->irq_map) | ||
122 | goto err2; | ||
123 | |||
124 | cb->int_max = max; | ||
125 | |||
126 | for (i = 0; i < max; i++) | ||
127 | cb->irq_map[i] = IRQ_FREE; | ||
128 | |||
129 | /* Get and mark reserved irqs */ | ||
130 | irqsr = of_get_property(node, "ti,irqs-reserved", &size); | ||
131 | if (irqsr) { | ||
132 | size /= sizeof(__be32); | ||
133 | |||
134 | for (i = 0; i < size; i++) { | ||
135 | of_property_read_u32_index(node, | ||
136 | "ti,irqs-reserved", | ||
137 | i, &entry); | ||
138 | if (entry > max) { | ||
139 | pr_err("Invalid reserved entry\n"); | ||
140 | goto err3; | ||
141 | } | ||
142 | cb->irq_map[entry] = 0; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | cb->register_offsets = kzalloc(max * sizeof(int), GFP_KERNEL); | ||
147 | if (!cb->register_offsets) | ||
148 | goto err3; | ||
149 | |||
150 | of_property_read_u32(node, "ti,reg-size", &size); | ||
151 | |||
152 | switch (size) { | ||
153 | case 1: | ||
154 | cb->write = crossbar_writeb; | ||
155 | break; | ||
156 | case 2: | ||
157 | cb->write = crossbar_writew; | ||
158 | break; | ||
159 | case 4: | ||
160 | cb->write = crossbar_writel; | ||
161 | break; | ||
162 | default: | ||
163 | pr_err("Invalid reg-size property\n"); | ||
164 | goto err4; | ||
165 | break; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Register offsets are not linear because of the | ||
170 | * reserved irqs. so find and store the offsets once. | ||
171 | */ | ||
172 | for (i = 0; i < max; i++) { | ||
173 | if (!cb->irq_map[i]) | ||
174 | continue; | ||
175 | |||
176 | cb->register_offsets[i] = reserved; | ||
177 | reserved += size; | ||
178 | } | ||
179 | |||
180 | register_routable_domain_ops(&routable_irq_domain_ops); | ||
181 | return 0; | ||
182 | |||
183 | err4: | ||
184 | kfree(cb->register_offsets); | ||
185 | err3: | ||
186 | kfree(cb->irq_map); | ||
187 | err2: | ||
188 | iounmap(cb->crossbar_base); | ||
189 | err1: | ||
190 | kfree(cb); | ||
191 | return -ENOMEM; | ||
192 | } | ||
193 | |||
194 | static const struct of_device_id crossbar_match[] __initconst = { | ||
195 | { .compatible = "ti,irq-crossbar" }, | ||
196 | {} | ||
197 | }; | ||
198 | |||
199 | int __init irqcrossbar_init(void) | ||
200 | { | ||
201 | struct device_node *np; | ||
202 | np = of_find_matching_node(NULL, crossbar_match); | ||
203 | if (!np) | ||
204 | return -ENODEV; | ||
205 | |||
206 | crossbar_of_init(np); | ||
207 | return 0; | ||
208 | } | ||
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 63922b9ba6b7..4300b6606f5e 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -824,16 +824,25 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, | |||
824 | irq_set_chip_and_handler(irq, &gic_chip, | 824 | irq_set_chip_and_handler(irq, &gic_chip, |
825 | handle_fasteoi_irq); | 825 | handle_fasteoi_irq); |
826 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 826 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
827 | |||
828 | gic_routable_irq_domain_ops->map(d, irq, hw); | ||
827 | } | 829 | } |
828 | irq_set_chip_data(irq, d->host_data); | 830 | irq_set_chip_data(irq, d->host_data); |
829 | return 0; | 831 | return 0; |
830 | } | 832 | } |
831 | 833 | ||
834 | static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq) | ||
835 | { | ||
836 | gic_routable_irq_domain_ops->unmap(d, irq); | ||
837 | } | ||
838 | |||
832 | static int gic_irq_domain_xlate(struct irq_domain *d, | 839 | static int gic_irq_domain_xlate(struct irq_domain *d, |
833 | struct device_node *controller, | 840 | struct device_node *controller, |
834 | const u32 *intspec, unsigned int intsize, | 841 | const u32 *intspec, unsigned int intsize, |
835 | unsigned long *out_hwirq, unsigned int *out_type) | 842 | unsigned long *out_hwirq, unsigned int *out_type) |
836 | { | 843 | { |
844 | unsigned long ret = 0; | ||
845 | |||
837 | if (d->of_node != controller) | 846 | if (d->of_node != controller) |
838 | return -EINVAL; | 847 | return -EINVAL; |
839 | if (intsize < 3) | 848 | if (intsize < 3) |
@@ -843,11 +852,20 @@ static int gic_irq_domain_xlate(struct irq_domain *d, | |||
843 | *out_hwirq = intspec[1] + 16; | 852 | *out_hwirq = intspec[1] + 16; |
844 | 853 | ||
845 | /* For SPIs, we need to add 16 more to get the GIC irq ID number */ | 854 | /* For SPIs, we need to add 16 more to get the GIC irq ID number */ |
846 | if (!intspec[0]) | 855 | if (!intspec[0]) { |
847 | *out_hwirq += 16; | 856 | ret = gic_routable_irq_domain_ops->xlate(d, controller, |
857 | intspec, | ||
858 | intsize, | ||
859 | out_hwirq, | ||
860 | out_type); | ||
861 | |||
862 | if (IS_ERR_VALUE(ret)) | ||
863 | return ret; | ||
864 | } | ||
848 | 865 | ||
849 | *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; | 866 | *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; |
850 | return 0; | 867 | |
868 | return ret; | ||
851 | } | 869 | } |
852 | 870 | ||
853 | #ifdef CONFIG_SMP | 871 | #ifdef CONFIG_SMP |
@@ -871,9 +889,41 @@ static struct notifier_block gic_cpu_notifier = { | |||
871 | 889 | ||
872 | static const struct irq_domain_ops gic_irq_domain_ops = { | 890 | static const struct irq_domain_ops gic_irq_domain_ops = { |
873 | .map = gic_irq_domain_map, | 891 | .map = gic_irq_domain_map, |
892 | .unmap = gic_irq_domain_unmap, | ||
874 | .xlate = gic_irq_domain_xlate, | 893 | .xlate = gic_irq_domain_xlate, |
875 | }; | 894 | }; |
876 | 895 | ||
896 | /* Default functions for routable irq domain */ | ||
897 | static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq, | ||
898 | irq_hw_number_t hw) | ||
899 | { | ||
900 | return 0; | ||
901 | } | ||
902 | |||
903 | static void gic_routable_irq_domain_unmap(struct irq_domain *d, | ||
904 | unsigned int irq) | ||
905 | { | ||
906 | } | ||
907 | |||
908 | static int gic_routable_irq_domain_xlate(struct irq_domain *d, | ||
909 | struct device_node *controller, | ||
910 | const u32 *intspec, unsigned int intsize, | ||
911 | unsigned long *out_hwirq, | ||
912 | unsigned int *out_type) | ||
913 | { | ||
914 | *out_hwirq += 16; | ||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | const struct irq_domain_ops gic_default_routable_irq_domain_ops = { | ||
919 | .map = gic_routable_irq_domain_map, | ||
920 | .unmap = gic_routable_irq_domain_unmap, | ||
921 | .xlate = gic_routable_irq_domain_xlate, | ||
922 | }; | ||
923 | |||
924 | const struct irq_domain_ops *gic_routable_irq_domain_ops = | ||
925 | &gic_default_routable_irq_domain_ops; | ||
926 | |||
877 | void __init gic_init_bases(unsigned int gic_nr, int irq_start, | 927 | void __init gic_init_bases(unsigned int gic_nr, int irq_start, |
878 | void __iomem *dist_base, void __iomem *cpu_base, | 928 | void __iomem *dist_base, void __iomem *cpu_base, |
879 | u32 percpu_offset, struct device_node *node) | 929 | u32 percpu_offset, struct device_node *node) |
@@ -881,6 +931,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
881 | irq_hw_number_t hwirq_base; | 931 | irq_hw_number_t hwirq_base; |
882 | struct gic_chip_data *gic; | 932 | struct gic_chip_data *gic; |
883 | int gic_irqs, irq_base, i; | 933 | int gic_irqs, irq_base, i; |
934 | int nr_routable_irqs; | ||
884 | 935 | ||
885 | BUG_ON(gic_nr >= MAX_GIC_NR); | 936 | BUG_ON(gic_nr >= MAX_GIC_NR); |
886 | 937 | ||
@@ -946,14 +997,25 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
946 | gic->gic_irqs = gic_irqs; | 997 | gic->gic_irqs = gic_irqs; |
947 | 998 | ||
948 | gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ | 999 | gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ |
949 | irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id()); | 1000 | |
950 | if (IS_ERR_VALUE(irq_base)) { | 1001 | if (of_property_read_u32(node, "arm,routable-irqs", |
951 | WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", | 1002 | &nr_routable_irqs)) { |
952 | irq_start); | 1003 | irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, |
953 | irq_base = irq_start; | 1004 | numa_node_id()); |
1005 | if (IS_ERR_VALUE(irq_base)) { | ||
1006 | WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", | ||
1007 | irq_start); | ||
1008 | irq_base = irq_start; | ||
1009 | } | ||
1010 | |||
1011 | gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base, | ||
1012 | hwirq_base, &gic_irq_domain_ops, gic); | ||
1013 | } else { | ||
1014 | gic->domain = irq_domain_add_linear(node, nr_routable_irqs, | ||
1015 | &gic_irq_domain_ops, | ||
1016 | gic); | ||
954 | } | 1017 | } |
955 | gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base, | 1018 | |
956 | hwirq_base, &gic_irq_domain_ops, gic); | ||
957 | if (WARN_ON(!gic->domain)) | 1019 | if (WARN_ON(!gic->domain)) |
958 | return; | 1020 | return; |
959 | 1021 | ||
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 473f09a74d4d..37dab0b472cd 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c | |||
@@ -57,6 +57,7 @@ | |||
57 | 57 | ||
58 | /** | 58 | /** |
59 | * struct vic_device - VIC PM device | 59 | * struct vic_device - VIC PM device |
60 | * @parent_irq: The parent IRQ number of the VIC if cascaded, or 0. | ||
60 | * @irq: The IRQ number for the base of the VIC. | 61 | * @irq: The IRQ number for the base of the VIC. |
61 | * @base: The register base for the VIC. | 62 | * @base: The register base for the VIC. |
62 | * @valid_sources: A bitmask of valid interrupts | 63 | * @valid_sources: A bitmask of valid interrupts |
@@ -224,6 +225,17 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) | |||
224 | return handled; | 225 | return handled; |
225 | } | 226 | } |
226 | 227 | ||
228 | static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc) | ||
229 | { | ||
230 | u32 stat, hwirq; | ||
231 | struct vic_device *vic = irq_desc_get_handler_data(desc); | ||
232 | |||
233 | while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { | ||
234 | hwirq = ffs(stat) - 1; | ||
235 | generic_handle_irq(irq_find_mapping(vic->domain, hwirq)); | ||
236 | } | ||
237 | } | ||
238 | |||
227 | /* | 239 | /* |
228 | * Keep iterating over all registered VIC's until there are no pending | 240 | * Keep iterating over all registered VIC's until there are no pending |
229 | * interrupts. | 241 | * interrupts. |
@@ -246,6 +258,7 @@ static struct irq_domain_ops vic_irqdomain_ops = { | |||
246 | /** | 258 | /** |
247 | * vic_register() - Register a VIC. | 259 | * vic_register() - Register a VIC. |
248 | * @base: The base address of the VIC. | 260 | * @base: The base address of the VIC. |
261 | * @parent_irq: The parent IRQ if cascaded, else 0. | ||
249 | * @irq: The base IRQ for the VIC. | 262 | * @irq: The base IRQ for the VIC. |
250 | * @valid_sources: bitmask of valid interrupts | 263 | * @valid_sources: bitmask of valid interrupts |
251 | * @resume_sources: bitmask of interrupts allowed for resume sources. | 264 | * @resume_sources: bitmask of interrupts allowed for resume sources. |
@@ -257,7 +270,8 @@ static struct irq_domain_ops vic_irqdomain_ops = { | |||
257 | * | 270 | * |
258 | * This also configures the IRQ domain for the VIC. | 271 | * This also configures the IRQ domain for the VIC. |
259 | */ | 272 | */ |
260 | static void __init vic_register(void __iomem *base, unsigned int irq, | 273 | static void __init vic_register(void __iomem *base, unsigned int parent_irq, |
274 | unsigned int irq, | ||
261 | u32 valid_sources, u32 resume_sources, | 275 | u32 valid_sources, u32 resume_sources, |
262 | struct device_node *node) | 276 | struct device_node *node) |
263 | { | 277 | { |
@@ -273,15 +287,25 @@ static void __init vic_register(void __iomem *base, unsigned int irq, | |||
273 | v->base = base; | 287 | v->base = base; |
274 | v->valid_sources = valid_sources; | 288 | v->valid_sources = valid_sources; |
275 | v->resume_sources = resume_sources; | 289 | v->resume_sources = resume_sources; |
276 | v->irq = irq; | ||
277 | set_handle_irq(vic_handle_irq); | 290 | set_handle_irq(vic_handle_irq); |
278 | vic_id++; | 291 | vic_id++; |
292 | |||
293 | if (parent_irq) { | ||
294 | irq_set_handler_data(parent_irq, v); | ||
295 | irq_set_chained_handler(parent_irq, vic_handle_irq_cascaded); | ||
296 | } | ||
297 | |||
279 | v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, | 298 | v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, |
280 | &vic_irqdomain_ops, v); | 299 | &vic_irqdomain_ops, v); |
281 | /* create an IRQ mapping for each valid IRQ */ | 300 | /* create an IRQ mapping for each valid IRQ */ |
282 | for (i = 0; i < fls(valid_sources); i++) | 301 | for (i = 0; i < fls(valid_sources); i++) |
283 | if (valid_sources & (1 << i)) | 302 | if (valid_sources & (1 << i)) |
284 | irq_create_mapping(v->domain, i); | 303 | irq_create_mapping(v->domain, i); |
304 | /* If no base IRQ was passed, figure out our allocated base */ | ||
305 | if (irq) | ||
306 | v->irq = irq; | ||
307 | else | ||
308 | v->irq = irq_find_mapping(v->domain, 0); | ||
285 | } | 309 | } |
286 | 310 | ||
287 | static void vic_ack_irq(struct irq_data *d) | 311 | static void vic_ack_irq(struct irq_data *d) |
@@ -409,10 +433,10 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, | |||
409 | writel(32, base + VIC_PL190_DEF_VECT_ADDR); | 433 | writel(32, base + VIC_PL190_DEF_VECT_ADDR); |
410 | } | 434 | } |
411 | 435 | ||
412 | vic_register(base, irq_start, vic_sources, 0, node); | 436 | vic_register(base, 0, irq_start, vic_sources, 0, node); |
413 | } | 437 | } |
414 | 438 | ||
415 | void __init __vic_init(void __iomem *base, int irq_start, | 439 | void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, |
416 | u32 vic_sources, u32 resume_sources, | 440 | u32 vic_sources, u32 resume_sources, |
417 | struct device_node *node) | 441 | struct device_node *node) |
418 | { | 442 | { |
@@ -449,7 +473,7 @@ void __init __vic_init(void __iomem *base, int irq_start, | |||
449 | 473 | ||
450 | vic_init2(base); | 474 | vic_init2(base); |
451 | 475 | ||
452 | vic_register(base, irq_start, vic_sources, resume_sources, node); | 476 | vic_register(base, parent_irq, irq_start, vic_sources, resume_sources, node); |
453 | } | 477 | } |
454 | 478 | ||
455 | /** | 479 | /** |
@@ -462,8 +486,30 @@ void __init __vic_init(void __iomem *base, int irq_start, | |||
462 | void __init vic_init(void __iomem *base, unsigned int irq_start, | 486 | void __init vic_init(void __iomem *base, unsigned int irq_start, |
463 | u32 vic_sources, u32 resume_sources) | 487 | u32 vic_sources, u32 resume_sources) |
464 | { | 488 | { |
465 | __vic_init(base, irq_start, vic_sources, resume_sources, NULL); | 489 | __vic_init(base, 0, irq_start, vic_sources, resume_sources, NULL); |
490 | } | ||
491 | |||
492 | /** | ||
493 | * vic_init_cascaded() - initialise a cascaded vectored interrupt controller | ||
494 | * @base: iomem base address | ||
495 | * @parent_irq: the parent IRQ we're cascaded off | ||
496 | * @irq_start: starting interrupt number, must be muliple of 32 | ||
497 | * @vic_sources: bitmask of interrupt sources to allow | ||
498 | * @resume_sources: bitmask of interrupt sources to allow for resume | ||
499 | * | ||
500 | * This returns the base for the new interrupts or negative on error. | ||
501 | */ | ||
502 | int __init vic_init_cascaded(void __iomem *base, unsigned int parent_irq, | ||
503 | u32 vic_sources, u32 resume_sources) | ||
504 | { | ||
505 | struct vic_device *v; | ||
506 | |||
507 | v = &vic_devices[vic_id]; | ||
508 | __vic_init(base, parent_irq, 0, vic_sources, resume_sources, NULL); | ||
509 | /* Return out acquired base */ | ||
510 | return v->irq; | ||
466 | } | 511 | } |
512 | EXPORT_SYMBOL_GPL(vic_init_cascaded); | ||
467 | 513 | ||
468 | #ifdef CONFIG_OF | 514 | #ifdef CONFIG_OF |
469 | int __init vic_of_init(struct device_node *node, struct device_node *parent) | 515 | int __init vic_of_init(struct device_node *node, struct device_node *parent) |
@@ -485,7 +531,7 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) | |||
485 | /* | 531 | /* |
486 | * Passing 0 as first IRQ makes the simple domain allocate descriptors | 532 | * Passing 0 as first IRQ makes the simple domain allocate descriptors |
487 | */ | 533 | */ |
488 | __vic_init(regs, 0, interrupt_mask, wakeup_mask, node); | 534 | __vic_init(regs, 0, 0, interrupt_mask, wakeup_mask, node); |
489 | 535 | ||
490 | return 0; | 536 | return 0; |
491 | } | 537 | } |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 72156c123033..44c358ecf5a1 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -421,7 +421,7 @@ config LEDS_MC13783 | |||
421 | config LEDS_NS2 | 421 | config LEDS_NS2 |
422 | tristate "LED support for Network Space v2 GPIO LEDs" | 422 | tristate "LED support for Network Space v2 GPIO LEDs" |
423 | depends on LEDS_CLASS | 423 | depends on LEDS_CLASS |
424 | depends on ARCH_KIRKWOOD | 424 | depends on ARCH_KIRKWOOD || MACH_KIRKWOOD |
425 | default y | 425 | default y |
426 | help | 426 | help |
427 | This option enable support for the dual-GPIO LED found on the | 427 | This option enable support for the dual-GPIO LED found on the |
@@ -431,7 +431,7 @@ config LEDS_NS2 | |||
431 | config LEDS_NETXBIG | 431 | config LEDS_NETXBIG |
432 | tristate "LED support for Big Network series LEDs" | 432 | tristate "LED support for Big Network series LEDs" |
433 | depends on LEDS_CLASS | 433 | depends on LEDS_CLASS |
434 | depends on ARCH_KIRKWOOD | 434 | depends on ARCH_KIRKWOOD || MACH_KIRKWOOD |
435 | default y | 435 | default y |
436 | help | 436 | help |
437 | This option enable support for LEDs found on the LaCie 2Big | 437 | This option enable support for LEDs found on the LaCie 2Big |
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index a4989ec6292e..8eb6a36f125a 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -746,28 +746,6 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
746 | goto err_clk_enable; | 746 | goto err_clk_enable; |
747 | } | 747 | } |
748 | 748 | ||
749 | /* | ||
750 | * Setup Async configuration register in case we did not boot from | ||
751 | * NAND and so bootloader did not bother to set it up. | ||
752 | */ | ||
753 | val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4); | ||
754 | |||
755 | /* Extended Wait is not valid and Select Strobe mode is not used */ | ||
756 | val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK); | ||
757 | if (info->chip.options & NAND_BUSWIDTH_16) | ||
758 | val |= 0x1; | ||
759 | |||
760 | davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val); | ||
761 | |||
762 | ret = 0; | ||
763 | if (info->timing) | ||
764 | ret = davinci_aemif_setup_timing(info->timing, info->base, | ||
765 | info->core_chipsel); | ||
766 | if (ret < 0) { | ||
767 | dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); | ||
768 | goto err; | ||
769 | } | ||
770 | |||
771 | spin_lock_irq(&davinci_nand_lock); | 749 | spin_lock_irq(&davinci_nand_lock); |
772 | 750 | ||
773 | /* put CSxNAND into NAND mode */ | 751 | /* put CSxNAND into NAND mode */ |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 8d3c49cc500f..3bb05f17b9b4 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -27,7 +27,7 @@ config PHY_EXYNOS_MIPI_VIDEO | |||
27 | 27 | ||
28 | config PHY_MVEBU_SATA | 28 | config PHY_MVEBU_SATA |
29 | def_bool y | 29 | def_bool y |
30 | depends on ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE | 30 | depends on ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD |
31 | depends on OF | 31 | depends on OF |
32 | select GENERIC_PHY | 32 | select GENERIC_PHY |
33 | 33 | ||
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 6d452a78b19c..fa0e4e057b99 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
@@ -22,7 +22,7 @@ config POWER_RESET_GPIO | |||
22 | 22 | ||
23 | config POWER_RESET_MSM | 23 | config POWER_RESET_MSM |
24 | bool "Qualcomm MSM power-off driver" | 24 | bool "Qualcomm MSM power-off driver" |
25 | depends on POWER_RESET && ARCH_MSM | 25 | depends on POWER_RESET && ARCH_QCOM |
26 | help | 26 | help |
27 | Power off and restart support for Qualcomm boards. | 27 | Power off and restart support for Qualcomm boards. |
28 | 28 | ||
diff --git a/drivers/power/reset/qnap-poweroff.c b/drivers/power/reset/qnap-poweroff.c index 37f56f7ee926..a75db7f8a92f 100644 --- a/drivers/power/reset/qnap-poweroff.c +++ b/drivers/power/reset/qnap-poweroff.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * QNAP Turbo NAS Board power off | 2 | * QNAP Turbo NAS Board power off. Can also be used on Synology devices. |
3 | * | 3 | * |
4 | * Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch> | 4 | * Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch> |
5 | * | 5 | * |
@@ -25,17 +25,43 @@ | |||
25 | 25 | ||
26 | #define UART1_REG(x) (base + ((UART_##x) << 2)) | 26 | #define UART1_REG(x) (base + ((UART_##x) << 2)) |
27 | 27 | ||
28 | struct power_off_cfg { | ||
29 | u32 baud; | ||
30 | char cmd; | ||
31 | }; | ||
32 | |||
33 | static const struct power_off_cfg qnap_power_off_cfg = { | ||
34 | .baud = 19200, | ||
35 | .cmd = 'A', | ||
36 | }; | ||
37 | |||
38 | static const struct power_off_cfg synology_power_off_cfg = { | ||
39 | .baud = 9600, | ||
40 | .cmd = '1', | ||
41 | }; | ||
42 | |||
43 | static const struct of_device_id qnap_power_off_of_match_table[] = { | ||
44 | { .compatible = "qnap,power-off", | ||
45 | .data = &qnap_power_off_cfg, | ||
46 | }, | ||
47 | { .compatible = "synology,power-off", | ||
48 | .data = &synology_power_off_cfg, | ||
49 | }, | ||
50 | {} | ||
51 | }; | ||
52 | MODULE_DEVICE_TABLE(of, qnap_power_off_of_match_table); | ||
53 | |||
28 | static void __iomem *base; | 54 | static void __iomem *base; |
29 | static unsigned long tclk; | 55 | static unsigned long tclk; |
56 | static const struct power_off_cfg *cfg; | ||
30 | 57 | ||
31 | static void qnap_power_off(void) | 58 | static void qnap_power_off(void) |
32 | { | 59 | { |
33 | /* 19200 baud divisor */ | 60 | const unsigned divisor = ((tclk + (8 * cfg->baud)) / (16 * cfg->baud)); |
34 | const unsigned divisor = ((tclk + (8 * 19200)) / (16 * 19200)); | ||
35 | 61 | ||
36 | pr_err("%s: triggering power-off...\n", __func__); | 62 | pr_err("%s: triggering power-off...\n", __func__); |
37 | 63 | ||
38 | /* hijack UART1 and reset into sane state (19200,8n1) */ | 64 | /* hijack UART1 and reset into sane state */ |
39 | writel(0x83, UART1_REG(LCR)); | 65 | writel(0x83, UART1_REG(LCR)); |
40 | writel(divisor & 0xff, UART1_REG(DLL)); | 66 | writel(divisor & 0xff, UART1_REG(DLL)); |
41 | writel((divisor >> 8) & 0xff, UART1_REG(DLM)); | 67 | writel((divisor >> 8) & 0xff, UART1_REG(DLM)); |
@@ -44,16 +70,21 @@ static void qnap_power_off(void) | |||
44 | writel(0x00, UART1_REG(FCR)); | 70 | writel(0x00, UART1_REG(FCR)); |
45 | writel(0x00, UART1_REG(MCR)); | 71 | writel(0x00, UART1_REG(MCR)); |
46 | 72 | ||
47 | /* send the power-off command 'A' to PIC */ | 73 | /* send the power-off command to PIC */ |
48 | writel('A', UART1_REG(TX)); | 74 | writel(cfg->cmd, UART1_REG(TX)); |
49 | } | 75 | } |
50 | 76 | ||
51 | static int qnap_power_off_probe(struct platform_device *pdev) | 77 | static int qnap_power_off_probe(struct platform_device *pdev) |
52 | { | 78 | { |
79 | struct device_node *np = pdev->dev.of_node; | ||
53 | struct resource *res; | 80 | struct resource *res; |
54 | struct clk *clk; | 81 | struct clk *clk; |
55 | char symname[KSYM_NAME_LEN]; | 82 | char symname[KSYM_NAME_LEN]; |
56 | 83 | ||
84 | const struct of_device_id *match = | ||
85 | of_match_node(qnap_power_off_of_match_table, np); | ||
86 | cfg = match->data; | ||
87 | |||
57 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 88 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
58 | if (!res) { | 89 | if (!res) { |
59 | dev_err(&pdev->dev, "Missing resource"); | 90 | dev_err(&pdev->dev, "Missing resource"); |
@@ -94,12 +125,6 @@ static int qnap_power_off_remove(struct platform_device *pdev) | |||
94 | return 0; | 125 | return 0; |
95 | } | 126 | } |
96 | 127 | ||
97 | static const struct of_device_id qnap_power_off_of_match_table[] = { | ||
98 | { .compatible = "qnap,power-off", }, | ||
99 | {} | ||
100 | }; | ||
101 | MODULE_DEVICE_TABLE(of, qnap_power_off_of_match_table); | ||
102 | |||
103 | static struct platform_driver qnap_power_off_driver = { | 128 | static struct platform_driver qnap_power_off_driver = { |
104 | .probe = qnap_power_off_probe, | 129 | .probe = qnap_power_off_probe, |
105 | .remove = qnap_power_off_remove, | 130 | .remove = qnap_power_off_remove, |
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index c9d04f797862..0615f50a14cd 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig | |||
@@ -11,3 +11,5 @@ menuconfig RESET_CONTROLLER | |||
11 | via GPIOs or SoC-internal reset controller modules. | 11 | via GPIOs or SoC-internal reset controller modules. |
12 | 12 | ||
13 | If unsure, say no. | 13 | If unsure, say no. |
14 | |||
15 | source "drivers/reset/sti/Kconfig" | ||
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index cc29832c9638..4f60caf750ce 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile | |||
@@ -1,2 +1,3 @@ | |||
1 | obj-$(CONFIG_RESET_CONTROLLER) += core.o | 1 | obj-$(CONFIG_RESET_CONTROLLER) += core.o |
2 | obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o | 2 | obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o |
3 | obj-$(CONFIG_ARCH_STI) += sti/ | ||
diff --git a/drivers/reset/core.c b/drivers/reset/core.c index d1b6089a0ef8..baeaf82d40d9 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c | |||
@@ -43,7 +43,7 @@ struct reset_control { | |||
43 | * This simple translation function should be used for reset controllers | 43 | * This simple translation function should be used for reset controllers |
44 | * with 1:1 mapping, where reset lines can be indexed by number without gaps. | 44 | * with 1:1 mapping, where reset lines can be indexed by number without gaps. |
45 | */ | 45 | */ |
46 | int of_reset_simple_xlate(struct reset_controller_dev *rcdev, | 46 | static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, |
47 | const struct of_phandle_args *reset_spec) | 47 | const struct of_phandle_args *reset_spec) |
48 | { | 48 | { |
49 | if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) | 49 | if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) |
@@ -54,7 +54,6 @@ int of_reset_simple_xlate(struct reset_controller_dev *rcdev, | |||
54 | 54 | ||
55 | return reset_spec->args[0]; | 55 | return reset_spec->args[0]; |
56 | } | 56 | } |
57 | EXPORT_SYMBOL_GPL(of_reset_simple_xlate); | ||
58 | 57 | ||
59 | /** | 58 | /** |
60 | * reset_controller_register - register a reset controller device | 59 | * reset_controller_register - register a reset controller device |
@@ -127,15 +126,16 @@ int reset_control_deassert(struct reset_control *rstc) | |||
127 | EXPORT_SYMBOL_GPL(reset_control_deassert); | 126 | EXPORT_SYMBOL_GPL(reset_control_deassert); |
128 | 127 | ||
129 | /** | 128 | /** |
130 | * reset_control_get - Lookup and obtain a reference to a reset controller. | 129 | * of_reset_control_get - Lookup and obtain a reference to a reset controller. |
131 | * @dev: device to be reset by the controller | 130 | * @node: device to be reset by the controller |
132 | * @id: reset line name | 131 | * @id: reset line name |
133 | * | 132 | * |
134 | * Returns a struct reset_control or IS_ERR() condition containing errno. | 133 | * Returns a struct reset_control or IS_ERR() condition containing errno. |
135 | * | 134 | * |
136 | * Use of id names is optional. | 135 | * Use of id names is optional. |
137 | */ | 136 | */ |
138 | struct reset_control *reset_control_get(struct device *dev, const char *id) | 137 | struct reset_control *of_reset_control_get(struct device_node *node, |
138 | const char *id) | ||
139 | { | 139 | { |
140 | struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); | 140 | struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); |
141 | struct reset_controller_dev *r, *rcdev; | 141 | struct reset_controller_dev *r, *rcdev; |
@@ -144,13 +144,10 @@ struct reset_control *reset_control_get(struct device *dev, const char *id) | |||
144 | int rstc_id; | 144 | int rstc_id; |
145 | int ret; | 145 | int ret; |
146 | 146 | ||
147 | if (!dev) | ||
148 | return ERR_PTR(-EINVAL); | ||
149 | |||
150 | if (id) | 147 | if (id) |
151 | index = of_property_match_string(dev->of_node, | 148 | index = of_property_match_string(node, |
152 | "reset-names", id); | 149 | "reset-names", id); |
153 | ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells", | 150 | ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", |
154 | index, &args); | 151 | index, &args); |
155 | if (ret) | 152 | if (ret) |
156 | return ERR_PTR(ret); | 153 | return ERR_PTR(ret); |
@@ -167,7 +164,7 @@ struct reset_control *reset_control_get(struct device *dev, const char *id) | |||
167 | 164 | ||
168 | if (!rcdev) { | 165 | if (!rcdev) { |
169 | mutex_unlock(&reset_controller_list_mutex); | 166 | mutex_unlock(&reset_controller_list_mutex); |
170 | return ERR_PTR(-ENODEV); | 167 | return ERR_PTR(-EPROBE_DEFER); |
171 | } | 168 | } |
172 | 169 | ||
173 | rstc_id = rcdev->of_xlate(rcdev, &args); | 170 | rstc_id = rcdev->of_xlate(rcdev, &args); |
@@ -185,12 +182,35 @@ struct reset_control *reset_control_get(struct device *dev, const char *id) | |||
185 | return ERR_PTR(-ENOMEM); | 182 | return ERR_PTR(-ENOMEM); |
186 | } | 183 | } |
187 | 184 | ||
188 | rstc->dev = dev; | ||
189 | rstc->rcdev = rcdev; | 185 | rstc->rcdev = rcdev; |
190 | rstc->id = rstc_id; | 186 | rstc->id = rstc_id; |
191 | 187 | ||
192 | return rstc; | 188 | return rstc; |
193 | } | 189 | } |
190 | EXPORT_SYMBOL_GPL(of_reset_control_get); | ||
191 | |||
192 | /** | ||
193 | * reset_control_get - Lookup and obtain a reference to a reset controller. | ||
194 | * @dev: device to be reset by the controller | ||
195 | * @id: reset line name | ||
196 | * | ||
197 | * Returns a struct reset_control or IS_ERR() condition containing errno. | ||
198 | * | ||
199 | * Use of id names is optional. | ||
200 | */ | ||
201 | struct reset_control *reset_control_get(struct device *dev, const char *id) | ||
202 | { | ||
203 | struct reset_control *rstc; | ||
204 | |||
205 | if (!dev) | ||
206 | return ERR_PTR(-EINVAL); | ||
207 | |||
208 | rstc = of_reset_control_get(dev->of_node, id); | ||
209 | if (!IS_ERR(rstc)) | ||
210 | rstc->dev = dev; | ||
211 | |||
212 | return rstc; | ||
213 | } | ||
194 | EXPORT_SYMBOL_GPL(reset_control_get); | 214 | EXPORT_SYMBOL_GPL(reset_control_get); |
195 | 215 | ||
196 | /** | 216 | /** |
@@ -243,33 +263,6 @@ struct reset_control *devm_reset_control_get(struct device *dev, const char *id) | |||
243 | } | 263 | } |
244 | EXPORT_SYMBOL_GPL(devm_reset_control_get); | 264 | EXPORT_SYMBOL_GPL(devm_reset_control_get); |
245 | 265 | ||
246 | static int devm_reset_control_match(struct device *dev, void *res, void *data) | ||
247 | { | ||
248 | struct reset_control **rstc = res; | ||
249 | if (WARN_ON(!rstc || !*rstc)) | ||
250 | return 0; | ||
251 | return *rstc == data; | ||
252 | } | ||
253 | |||
254 | /** | ||
255 | * devm_reset_control_put - resource managed reset_control_put() | ||
256 | * @rstc: reset controller to free | ||
257 | * | ||
258 | * Deallocate a reset control allocated withd devm_reset_control_get(). | ||
259 | * This function will not need to be called normally, as devres will take | ||
260 | * care of freeing the resource. | ||
261 | */ | ||
262 | void devm_reset_control_put(struct reset_control *rstc) | ||
263 | { | ||
264 | int ret; | ||
265 | |||
266 | ret = devres_release(rstc->dev, devm_reset_control_release, | ||
267 | devm_reset_control_match, rstc); | ||
268 | if (ret) | ||
269 | WARN_ON(ret); | ||
270 | } | ||
271 | EXPORT_SYMBOL_GPL(devm_reset_control_put); | ||
272 | |||
273 | /** | 266 | /** |
274 | * device_reset - find reset controller associated with the device | 267 | * device_reset - find reset controller associated with the device |
275 | * and perform reset | 268 | * and perform reset |
diff --git a/drivers/reset/sti/Kconfig b/drivers/reset/sti/Kconfig new file mode 100644 index 000000000000..88d2d0316613 --- /dev/null +++ b/drivers/reset/sti/Kconfig | |||
@@ -0,0 +1,15 @@ | |||
1 | if ARCH_STI | ||
2 | |||
3 | config STI_RESET_SYSCFG | ||
4 | bool | ||
5 | select RESET_CONTROLLER | ||
6 | |||
7 | config STIH415_RESET | ||
8 | bool | ||
9 | select STI_RESET_SYSCFG | ||
10 | |||
11 | config STIH416_RESET | ||
12 | bool | ||
13 | select STI_RESET_SYSCFG | ||
14 | |||
15 | endif | ||
diff --git a/drivers/reset/sti/Makefile b/drivers/reset/sti/Makefile new file mode 100644 index 000000000000..be1c97647871 --- /dev/null +++ b/drivers/reset/sti/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | obj-$(CONFIG_STI_RESET_SYSCFG) += reset-syscfg.o | ||
2 | |||
3 | obj-$(CONFIG_STIH415_RESET) += reset-stih415.o | ||
4 | obj-$(CONFIG_STIH416_RESET) += reset-stih416.o | ||
diff --git a/drivers/reset/sti/reset-stih415.c b/drivers/reset/sti/reset-stih415.c new file mode 100644 index 000000000000..e6f6c41abe12 --- /dev/null +++ b/drivers/reset/sti/reset-stih415.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 STMicroelectronics (R&D) Limited | ||
3 | * Author: Stephen Gallimore <stephen.gallimore@st.com> | ||
4 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/of.h> | ||
13 | #include <linux/of_platform.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | #include <dt-bindings/reset-controller/stih415-resets.h> | ||
17 | |||
18 | #include "reset-syscfg.h" | ||
19 | |||
20 | /* | ||
21 | * STiH415 Peripheral powerdown definitions. | ||
22 | */ | ||
23 | static const char stih415_front[] = "st,stih415-front-syscfg"; | ||
24 | static const char stih415_rear[] = "st,stih415-rear-syscfg"; | ||
25 | static const char stih415_sbc[] = "st,stih415-sbc-syscfg"; | ||
26 | static const char stih415_lpm[] = "st,stih415-lpm-syscfg"; | ||
27 | |||
28 | #define STIH415_PDN_FRONT(_bit) \ | ||
29 | _SYSCFG_RST_CH(stih415_front, SYSCFG_114, _bit, SYSSTAT_187, _bit) | ||
30 | |||
31 | #define STIH415_PDN_REAR(_cntl, _stat) \ | ||
32 | _SYSCFG_RST_CH(stih415_rear, SYSCFG_336, _cntl, SYSSTAT_384, _stat) | ||
33 | |||
34 | #define STIH415_SRST_REAR(_reg, _bit) \ | ||
35 | _SYSCFG_RST_CH_NO_ACK(stih415_rear, _reg, _bit) | ||
36 | |||
37 | #define STIH415_SRST_SBC(_reg, _bit) \ | ||
38 | _SYSCFG_RST_CH_NO_ACK(stih415_sbc, _reg, _bit) | ||
39 | |||
40 | #define STIH415_SRST_FRONT(_reg, _bit) \ | ||
41 | _SYSCFG_RST_CH_NO_ACK(stih415_front, _reg, _bit) | ||
42 | |||
43 | #define STIH415_SRST_LPM(_reg, _bit) \ | ||
44 | _SYSCFG_RST_CH_NO_ACK(stih415_lpm, _reg, _bit) | ||
45 | |||
46 | #define SYSCFG_114 0x38 /* Powerdown request EMI/NAND/Keyscan */ | ||
47 | #define SYSSTAT_187 0x15c /* Powerdown status EMI/NAND/Keyscan */ | ||
48 | |||
49 | #define SYSCFG_336 0x90 /* Powerdown request USB/SATA/PCIe */ | ||
50 | #define SYSSTAT_384 0x150 /* Powerdown status USB/SATA/PCIe */ | ||
51 | |||
52 | #define SYSCFG_376 0x130 /* Reset generator 0 control 0 */ | ||
53 | #define SYSCFG_166 0x108 /* Softreset Ethernet 0 */ | ||
54 | #define SYSCFG_31 0x7c /* Softreset Ethernet 1 */ | ||
55 | #define LPM_SYSCFG_1 0x4 /* Softreset IRB */ | ||
56 | |||
57 | static const struct syscfg_reset_channel_data stih415_powerdowns[] = { | ||
58 | [STIH415_EMISS_POWERDOWN] = STIH415_PDN_FRONT(0), | ||
59 | [STIH415_NAND_POWERDOWN] = STIH415_PDN_FRONT(1), | ||
60 | [STIH415_KEYSCAN_POWERDOWN] = STIH415_PDN_FRONT(2), | ||
61 | [STIH415_USB0_POWERDOWN] = STIH415_PDN_REAR(0, 0), | ||
62 | [STIH415_USB1_POWERDOWN] = STIH415_PDN_REAR(1, 1), | ||
63 | [STIH415_USB2_POWERDOWN] = STIH415_PDN_REAR(2, 2), | ||
64 | [STIH415_SATA0_POWERDOWN] = STIH415_PDN_REAR(3, 3), | ||
65 | [STIH415_SATA1_POWERDOWN] = STIH415_PDN_REAR(4, 4), | ||
66 | [STIH415_PCIE_POWERDOWN] = STIH415_PDN_REAR(5, 8), | ||
67 | }; | ||
68 | |||
69 | static const struct syscfg_reset_channel_data stih415_softresets[] = { | ||
70 | [STIH415_ETH0_SOFTRESET] = STIH415_SRST_FRONT(SYSCFG_166, 0), | ||
71 | [STIH415_ETH1_SOFTRESET] = STIH415_SRST_SBC(SYSCFG_31, 0), | ||
72 | [STIH415_IRB_SOFTRESET] = STIH415_SRST_LPM(LPM_SYSCFG_1, 6), | ||
73 | [STIH415_USB0_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 9), | ||
74 | [STIH415_USB1_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 10), | ||
75 | [STIH415_USB2_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 11), | ||
76 | }; | ||
77 | |||
78 | static struct syscfg_reset_controller_data stih415_powerdown_controller = { | ||
79 | .wait_for_ack = true, | ||
80 | .nr_channels = ARRAY_SIZE(stih415_powerdowns), | ||
81 | .channels = stih415_powerdowns, | ||
82 | }; | ||
83 | |||
84 | static struct syscfg_reset_controller_data stih415_softreset_controller = { | ||
85 | .wait_for_ack = false, | ||
86 | .active_low = true, | ||
87 | .nr_channels = ARRAY_SIZE(stih415_softresets), | ||
88 | .channels = stih415_softresets, | ||
89 | }; | ||
90 | |||
91 | static struct of_device_id stih415_reset_match[] = { | ||
92 | { .compatible = "st,stih415-powerdown", | ||
93 | .data = &stih415_powerdown_controller, }, | ||
94 | { .compatible = "st,stih415-softreset", | ||
95 | .data = &stih415_softreset_controller, }, | ||
96 | {}, | ||
97 | }; | ||
98 | |||
99 | static struct platform_driver stih415_reset_driver = { | ||
100 | .probe = syscfg_reset_probe, | ||
101 | .driver = { | ||
102 | .name = "reset-stih415", | ||
103 | .owner = THIS_MODULE, | ||
104 | .of_match_table = stih415_reset_match, | ||
105 | }, | ||
106 | }; | ||
107 | |||
108 | static int __init stih415_reset_init(void) | ||
109 | { | ||
110 | return platform_driver_register(&stih415_reset_driver); | ||
111 | } | ||
112 | arch_initcall(stih415_reset_init); | ||
diff --git a/drivers/reset/sti/reset-stih416.c b/drivers/reset/sti/reset-stih416.c new file mode 100644 index 000000000000..fe3bf02bdc8c --- /dev/null +++ b/drivers/reset/sti/reset-stih416.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 STMicroelectronics (R&D) Limited | ||
3 | * Author: Stephen Gallimore <stephen.gallimore@st.com> | ||
4 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/of.h> | ||
13 | #include <linux/of_platform.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | #include <dt-bindings/reset-controller/stih416-resets.h> | ||
17 | |||
18 | #include "reset-syscfg.h" | ||
19 | |||
20 | /* | ||
21 | * STiH416 Peripheral powerdown definitions. | ||
22 | */ | ||
23 | static const char stih416_front[] = "st,stih416-front-syscfg"; | ||
24 | static const char stih416_rear[] = "st,stih416-rear-syscfg"; | ||
25 | static const char stih416_sbc[] = "st,stih416-sbc-syscfg"; | ||
26 | static const char stih416_lpm[] = "st,stih416-lpm-syscfg"; | ||
27 | static const char stih416_cpu[] = "st,stih416-cpu-syscfg"; | ||
28 | |||
29 | #define STIH416_PDN_FRONT(_bit) \ | ||
30 | _SYSCFG_RST_CH(stih416_front, SYSCFG_1500, _bit, SYSSTAT_1578, _bit) | ||
31 | |||
32 | #define STIH416_PDN_REAR(_cntl, _stat) \ | ||
33 | _SYSCFG_RST_CH(stih416_rear, SYSCFG_2525, _cntl, SYSSTAT_2583, _stat) | ||
34 | |||
35 | #define SYSCFG_1500 0x7d0 /* Powerdown request EMI/NAND/Keyscan */ | ||
36 | #define SYSSTAT_1578 0x908 /* Powerdown status EMI/NAND/Keyscan */ | ||
37 | |||
38 | #define SYSCFG_2525 0x834 /* Powerdown request USB/SATA/PCIe */ | ||
39 | #define SYSSTAT_2583 0x91c /* Powerdown status USB/SATA/PCIe */ | ||
40 | |||
41 | #define SYSCFG_2552 0x8A0 /* Reset Generator control 0 */ | ||
42 | #define SYSCFG_1539 0x86c /* Softreset Ethernet 0 */ | ||
43 | #define SYSCFG_510 0x7f8 /* Softreset Ethernet 1 */ | ||
44 | #define LPM_SYSCFG_1 0x4 /* Softreset IRB */ | ||
45 | #define SYSCFG_2553 0x8a4 /* Softreset SATA0/1, PCIE0/1 */ | ||
46 | #define SYSCFG_7563 0x8cc /* MPE softresets 0 */ | ||
47 | #define SYSCFG_7564 0x8d0 /* MPE softresets 1 */ | ||
48 | |||
49 | #define STIH416_SRST_CPU(_reg, _bit) \ | ||
50 | _SYSCFG_RST_CH_NO_ACK(stih416_cpu, _reg, _bit) | ||
51 | |||
52 | #define STIH416_SRST_FRONT(_reg, _bit) \ | ||
53 | _SYSCFG_RST_CH_NO_ACK(stih416_front, _reg, _bit) | ||
54 | |||
55 | #define STIH416_SRST_REAR(_reg, _bit) \ | ||
56 | _SYSCFG_RST_CH_NO_ACK(stih416_rear, _reg, _bit) | ||
57 | |||
58 | #define STIH416_SRST_LPM(_reg, _bit) \ | ||
59 | _SYSCFG_RST_CH_NO_ACK(stih416_lpm, _reg, _bit) | ||
60 | |||
61 | #define STIH416_SRST_SBC(_reg, _bit) \ | ||
62 | _SYSCFG_RST_CH_NO_ACK(stih416_sbc, _reg, _bit) | ||
63 | |||
64 | static const struct syscfg_reset_channel_data stih416_powerdowns[] = { | ||
65 | [STIH416_EMISS_POWERDOWN] = STIH416_PDN_FRONT(0), | ||
66 | [STIH416_NAND_POWERDOWN] = STIH416_PDN_FRONT(1), | ||
67 | [STIH416_KEYSCAN_POWERDOWN] = STIH416_PDN_FRONT(2), | ||
68 | [STIH416_USB0_POWERDOWN] = STIH416_PDN_REAR(0, 0), | ||
69 | [STIH416_USB1_POWERDOWN] = STIH416_PDN_REAR(1, 1), | ||
70 | [STIH416_USB2_POWERDOWN] = STIH416_PDN_REAR(2, 2), | ||
71 | [STIH416_USB3_POWERDOWN] = STIH416_PDN_REAR(6, 5), | ||
72 | [STIH416_SATA0_POWERDOWN] = STIH416_PDN_REAR(3, 3), | ||
73 | [STIH416_SATA1_POWERDOWN] = STIH416_PDN_REAR(4, 4), | ||
74 | [STIH416_PCIE0_POWERDOWN] = STIH416_PDN_REAR(7, 9), | ||
75 | [STIH416_PCIE1_POWERDOWN] = STIH416_PDN_REAR(5, 8), | ||
76 | }; | ||
77 | |||
78 | static const struct syscfg_reset_channel_data stih416_softresets[] = { | ||
79 | [STIH416_ETH0_SOFTRESET] = STIH416_SRST_FRONT(SYSCFG_1539, 0), | ||
80 | [STIH416_ETH1_SOFTRESET] = STIH416_SRST_SBC(SYSCFG_510, 0), | ||
81 | [STIH416_IRB_SOFTRESET] = STIH416_SRST_LPM(LPM_SYSCFG_1, 6), | ||
82 | [STIH416_USB0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 9), | ||
83 | [STIH416_USB1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 10), | ||
84 | [STIH416_USB2_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 11), | ||
85 | [STIH416_USB3_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 28), | ||
86 | [STIH416_SATA0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 7), | ||
87 | [STIH416_SATA1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 3), | ||
88 | [STIH416_PCIE0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 15), | ||
89 | [STIH416_PCIE1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 2), | ||
90 | [STIH416_AUD_DAC_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 14), | ||
91 | [STIH416_HDTVOUT_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 5), | ||
92 | [STIH416_VTAC_M_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 25), | ||
93 | [STIH416_VTAC_A_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 26), | ||
94 | [STIH416_SYNC_HD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 5), | ||
95 | [STIH416_SYNC_SD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 6), | ||
96 | [STIH416_BLITTER_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 10), | ||
97 | [STIH416_GPU_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 11), | ||
98 | [STIH416_VTAC_M_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 18), | ||
99 | [STIH416_VTAC_A_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 19), | ||
100 | [STIH416_VTG_AUX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 21), | ||
101 | [STIH416_JPEG_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 23), | ||
102 | [STIH416_HVA_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 2), | ||
103 | [STIH416_COMPO_M_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 3), | ||
104 | [STIH416_COMPO_A_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 4), | ||
105 | [STIH416_VP8_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 10), | ||
106 | [STIH416_VTG_MAIN_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 16), | ||
107 | }; | ||
108 | |||
109 | static struct syscfg_reset_controller_data stih416_powerdown_controller = { | ||
110 | .wait_for_ack = true, | ||
111 | .nr_channels = ARRAY_SIZE(stih416_powerdowns), | ||
112 | .channels = stih416_powerdowns, | ||
113 | }; | ||
114 | |||
115 | static struct syscfg_reset_controller_data stih416_softreset_controller = { | ||
116 | .wait_for_ack = false, | ||
117 | .active_low = true, | ||
118 | .nr_channels = ARRAY_SIZE(stih416_softresets), | ||
119 | .channels = stih416_softresets, | ||
120 | }; | ||
121 | |||
122 | static struct of_device_id stih416_reset_match[] = { | ||
123 | { .compatible = "st,stih416-powerdown", | ||
124 | .data = &stih416_powerdown_controller, }, | ||
125 | { .compatible = "st,stih416-softreset", | ||
126 | .data = &stih416_softreset_controller, }, | ||
127 | {}, | ||
128 | }; | ||
129 | |||
130 | static struct platform_driver stih416_reset_driver = { | ||
131 | .probe = syscfg_reset_probe, | ||
132 | .driver = { | ||
133 | .name = "reset-stih416", | ||
134 | .owner = THIS_MODULE, | ||
135 | .of_match_table = stih416_reset_match, | ||
136 | }, | ||
137 | }; | ||
138 | |||
139 | static int __init stih416_reset_init(void) | ||
140 | { | ||
141 | return platform_driver_register(&stih416_reset_driver); | ||
142 | } | ||
143 | arch_initcall(stih416_reset_init); | ||
diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c new file mode 100644 index 000000000000..a145cc066d4a --- /dev/null +++ b/drivers/reset/sti/reset-syscfg.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 STMicroelectronics Limited | ||
3 | * Author: Stephen Gallimore <stephen.gallimore@st.com> | ||
4 | * | ||
5 | * Inspired by mach-imx/src.c | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/mfd/syscon.h> | ||
20 | |||
21 | #include "reset-syscfg.h" | ||
22 | |||
23 | /** | ||
24 | * Reset channel regmap configuration | ||
25 | * | ||
26 | * @reset: regmap field for the channel's reset bit. | ||
27 | * @ack: regmap field for the channel's ack bit (optional). | ||
28 | */ | ||
29 | struct syscfg_reset_channel { | ||
30 | struct regmap_field *reset; | ||
31 | struct regmap_field *ack; | ||
32 | }; | ||
33 | |||
34 | /** | ||
35 | * A reset controller which groups together a set of related reset bits, which | ||
36 | * may be located in different system configuration registers. | ||
37 | * | ||
38 | * @rst: base reset controller structure. | ||
39 | * @active_low: are the resets in this controller active low, i.e. clearing | ||
40 | * the reset bit puts the hardware into reset. | ||
41 | * @channels: An array of reset channels for this controller. | ||
42 | */ | ||
43 | struct syscfg_reset_controller { | ||
44 | struct reset_controller_dev rst; | ||
45 | bool active_low; | ||
46 | struct syscfg_reset_channel *channels; | ||
47 | }; | ||
48 | |||
49 | #define to_syscfg_reset_controller(_rst) \ | ||
50 | container_of(_rst, struct syscfg_reset_controller, rst) | ||
51 | |||
52 | static int syscfg_reset_program_hw(struct reset_controller_dev *rcdev, | ||
53 | unsigned long idx, int assert) | ||
54 | { | ||
55 | struct syscfg_reset_controller *rst = to_syscfg_reset_controller(rcdev); | ||
56 | const struct syscfg_reset_channel *ch; | ||
57 | u32 ctrl_val = rst->active_low ? !assert : !!assert; | ||
58 | int err; | ||
59 | |||
60 | if (idx >= rcdev->nr_resets) | ||
61 | return -EINVAL; | ||
62 | |||
63 | ch = &rst->channels[idx]; | ||
64 | |||
65 | err = regmap_field_write(ch->reset, ctrl_val); | ||
66 | if (err) | ||
67 | return err; | ||
68 | |||
69 | if (ch->ack) { | ||
70 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | ||
71 | u32 ack_val; | ||
72 | |||
73 | while (true) { | ||
74 | err = regmap_field_read(ch->ack, &ack_val); | ||
75 | if (err) | ||
76 | return err; | ||
77 | |||
78 | if (ack_val == ctrl_val) | ||
79 | break; | ||
80 | |||
81 | if (time_after(jiffies, timeout)) | ||
82 | return -ETIME; | ||
83 | |||
84 | cpu_relax(); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int syscfg_reset_assert(struct reset_controller_dev *rcdev, | ||
92 | unsigned long idx) | ||
93 | { | ||
94 | return syscfg_reset_program_hw(rcdev, idx, true); | ||
95 | } | ||
96 | |||
97 | static int syscfg_reset_deassert(struct reset_controller_dev *rcdev, | ||
98 | unsigned long idx) | ||
99 | { | ||
100 | return syscfg_reset_program_hw(rcdev, idx, false); | ||
101 | } | ||
102 | |||
103 | static int syscfg_reset_dev(struct reset_controller_dev *rcdev, | ||
104 | unsigned long idx) | ||
105 | { | ||
106 | int err = syscfg_reset_assert(rcdev, idx); | ||
107 | if (err) | ||
108 | return err; | ||
109 | |||
110 | return syscfg_reset_deassert(rcdev, idx); | ||
111 | } | ||
112 | |||
113 | static struct reset_control_ops syscfg_reset_ops = { | ||
114 | .reset = syscfg_reset_dev, | ||
115 | .assert = syscfg_reset_assert, | ||
116 | .deassert = syscfg_reset_deassert, | ||
117 | }; | ||
118 | |||
119 | static int syscfg_reset_controller_register(struct device *dev, | ||
120 | const struct syscfg_reset_controller_data *data) | ||
121 | { | ||
122 | struct syscfg_reset_controller *rc; | ||
123 | size_t size; | ||
124 | int i, err; | ||
125 | |||
126 | rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL); | ||
127 | if (!rc) | ||
128 | return -ENOMEM; | ||
129 | |||
130 | size = sizeof(struct syscfg_reset_channel) * data->nr_channels; | ||
131 | |||
132 | rc->channels = devm_kzalloc(dev, size, GFP_KERNEL); | ||
133 | if (!rc->channels) | ||
134 | return -ENOMEM; | ||
135 | |||
136 | rc->rst.ops = &syscfg_reset_ops, | ||
137 | rc->rst.of_node = dev->of_node; | ||
138 | rc->rst.nr_resets = data->nr_channels; | ||
139 | rc->active_low = data->active_low; | ||
140 | |||
141 | for (i = 0; i < data->nr_channels; i++) { | ||
142 | struct regmap *map; | ||
143 | struct regmap_field *f; | ||
144 | const char *compatible = data->channels[i].compatible; | ||
145 | |||
146 | map = syscon_regmap_lookup_by_compatible(compatible); | ||
147 | if (IS_ERR(map)) | ||
148 | return PTR_ERR(map); | ||
149 | |||
150 | f = devm_regmap_field_alloc(dev, map, data->channels[i].reset); | ||
151 | if (IS_ERR(f)) | ||
152 | return PTR_ERR(f); | ||
153 | |||
154 | rc->channels[i].reset = f; | ||
155 | |||
156 | if (!data->wait_for_ack) | ||
157 | continue; | ||
158 | |||
159 | f = devm_regmap_field_alloc(dev, map, data->channels[i].ack); | ||
160 | if (IS_ERR(f)) | ||
161 | return PTR_ERR(f); | ||
162 | |||
163 | rc->channels[i].ack = f; | ||
164 | } | ||
165 | |||
166 | err = reset_controller_register(&rc->rst); | ||
167 | if (!err) | ||
168 | dev_info(dev, "registered\n"); | ||
169 | |||
170 | return err; | ||
171 | } | ||
172 | |||
173 | int syscfg_reset_probe(struct platform_device *pdev) | ||
174 | { | ||
175 | struct device *dev = pdev ? &pdev->dev : NULL; | ||
176 | const struct of_device_id *match; | ||
177 | |||
178 | if (!dev || !dev->driver) | ||
179 | return -ENODEV; | ||
180 | |||
181 | match = of_match_device(dev->driver->of_match_table, dev); | ||
182 | if (!match || !match->data) | ||
183 | return -EINVAL; | ||
184 | |||
185 | return syscfg_reset_controller_register(dev, match->data); | ||
186 | } | ||
diff --git a/drivers/reset/sti/reset-syscfg.h b/drivers/reset/sti/reset-syscfg.h new file mode 100644 index 000000000000..2cc2283bac40 --- /dev/null +++ b/drivers/reset/sti/reset-syscfg.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 STMicroelectronics (R&D) Limited | ||
3 | * Author: Stephen Gallimore <stephen.gallimore@st.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | ||
10 | #ifndef __STI_RESET_SYSCFG_H | ||
11 | #define __STI_RESET_SYSCFG_H | ||
12 | |||
13 | #include <linux/device.h> | ||
14 | #include <linux/regmap.h> | ||
15 | #include <linux/reset-controller.h> | ||
16 | |||
17 | /** | ||
18 | * Reset channel description for a system configuration register based | ||
19 | * reset controller. | ||
20 | * | ||
21 | * @compatible: Compatible string of the syscon regmap containing this | ||
22 | * channel's control and ack (status) bits. | ||
23 | * @reset: Regmap field description of the channel's reset bit. | ||
24 | * @ack: Regmap field description of the channel's acknowledge bit. | ||
25 | */ | ||
26 | struct syscfg_reset_channel_data { | ||
27 | const char *compatible; | ||
28 | struct reg_field reset; | ||
29 | struct reg_field ack; | ||
30 | }; | ||
31 | |||
32 | #define _SYSCFG_RST_CH(_c, _rr, _rb, _ar, _ab) \ | ||
33 | { .compatible = _c, \ | ||
34 | .reset = REG_FIELD(_rr, _rb, _rb), \ | ||
35 | .ack = REG_FIELD(_ar, _ab, _ab), } | ||
36 | |||
37 | #define _SYSCFG_RST_CH_NO_ACK(_c, _rr, _rb) \ | ||
38 | { .compatible = _c, \ | ||
39 | .reset = REG_FIELD(_rr, _rb, _rb), } | ||
40 | |||
41 | /** | ||
42 | * Description of a system configuration register based reset controller. | ||
43 | * | ||
44 | * @wait_for_ack: The controller will wait for reset assert and de-assert to | ||
45 | * be "ack'd" in a channel's ack field. | ||
46 | * @active_low: Are the resets in this controller active low, i.e. clearing | ||
47 | * the reset bit puts the hardware into reset. | ||
48 | * @nr_channels: The number of reset channels in this controller. | ||
49 | * @channels: An array of reset channel descriptions. | ||
50 | */ | ||
51 | struct syscfg_reset_controller_data { | ||
52 | bool wait_for_ack; | ||
53 | bool active_low; | ||
54 | int nr_channels; | ||
55 | const struct syscfg_reset_channel_data *channels; | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * syscfg_reset_probe(): platform device probe function used by syscfg | ||
60 | * reset controller drivers. This registers a reset | ||
61 | * controller configured by the OF match data for | ||
62 | * the compatible device which should be of type | ||
63 | * "struct syscfg_reset_controller_data". | ||
64 | * | ||
65 | * @pdev: platform device | ||
66 | */ | ||
67 | int syscfg_reset_probe(struct platform_device *pdev); | ||
68 | |||
69 | #endif /* __STI_RESET_SYSCFG_H */ | ||
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c index 7e5ead936a04..41bd76aaff76 100644 --- a/drivers/rtc/rtc-isl12057.c +++ b/drivers/rtc/rtc-isl12057.c | |||
@@ -274,10 +274,7 @@ static int isl12057_probe(struct i2c_client *client, | |||
274 | dev_set_drvdata(dev, data); | 274 | dev_set_drvdata(dev, data); |
275 | 275 | ||
276 | rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, THIS_MODULE); | 276 | rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, THIS_MODULE); |
277 | if (IS_ERR(rtc)) | 277 | return PTR_ERR_OR_ZERO(rtc); |
278 | return PTR_ERR(rtc); | ||
279 | |||
280 | return 0; | ||
281 | } | 278 | } |
282 | 279 | ||
283 | #ifdef CONFIG_OF | 280 | #ifdef CONFIG_OF |
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index d536c5962c99..d15a999363fc 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c | |||
@@ -222,6 +222,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev) | |||
222 | struct resource *res; | 222 | struct resource *res; |
223 | struct rtc_plat_data *pdata; | 223 | struct rtc_plat_data *pdata; |
224 | u32 rtc_time; | 224 | u32 rtc_time; |
225 | u32 rtc_date; | ||
225 | int ret = 0; | 226 | int ret = 0; |
226 | 227 | ||
227 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 228 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
@@ -257,6 +258,17 @@ static int __init mv_rtc_probe(struct platform_device *pdev) | |||
257 | } | 258 | } |
258 | } | 259 | } |
259 | 260 | ||
261 | /* | ||
262 | * A date after January 19th, 2038 does not fit on 32 bits and | ||
263 | * will confuse the kernel and userspace. Reset to a sane date | ||
264 | * (January 1st, 2013) if we're after 2038. | ||
265 | */ | ||
266 | rtc_date = readl(pdata->ioaddr + RTC_DATE_REG_OFFS); | ||
267 | if (bcd2bin((rtc_date >> RTC_YEAR_OFFS) & 0xff) >= 38) { | ||
268 | dev_info(&pdev->dev, "invalid RTC date, resetting to January 1st, 2013\n"); | ||
269 | writel(0x130101, pdata->ioaddr + RTC_DATE_REG_OFFS); | ||
270 | } | ||
271 | |||
260 | pdata->irq = platform_get_irq(pdev, 0); | 272 | pdata->irq = platform_get_irq(pdev, 0); |
261 | 273 | ||
262 | platform_set_drvdata(pdev, pdata); | 274 | platform_set_drvdata(pdev, pdata); |
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 1ebe67cd1833..7442bc130055 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c | |||
@@ -36,9 +36,47 @@ static void sh_clk_write(int value, struct clk *clk) | |||
36 | iowrite32(value, clk->mapped_reg); | 36 | iowrite32(value, clk->mapped_reg); |
37 | } | 37 | } |
38 | 38 | ||
39 | static unsigned int r8(const void __iomem *addr) | ||
40 | { | ||
41 | return ioread8(addr); | ||
42 | } | ||
43 | |||
44 | static unsigned int r16(const void __iomem *addr) | ||
45 | { | ||
46 | return ioread16(addr); | ||
47 | } | ||
48 | |||
49 | static unsigned int r32(const void __iomem *addr) | ||
50 | { | ||
51 | return ioread32(addr); | ||
52 | } | ||
53 | |||
39 | static int sh_clk_mstp_enable(struct clk *clk) | 54 | static int sh_clk_mstp_enable(struct clk *clk) |
40 | { | 55 | { |
41 | sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); | 56 | sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); |
57 | if (clk->status_reg) { | ||
58 | unsigned int (*read)(const void __iomem *addr); | ||
59 | int i; | ||
60 | void __iomem *mapped_status = (phys_addr_t)clk->status_reg - | ||
61 | (phys_addr_t)clk->enable_reg + clk->mapped_reg; | ||
62 | |||
63 | if (clk->flags & CLK_ENABLE_REG_8BIT) | ||
64 | read = r8; | ||
65 | else if (clk->flags & CLK_ENABLE_REG_16BIT) | ||
66 | read = r16; | ||
67 | else | ||
68 | read = r32; | ||
69 | |||
70 | for (i = 1000; | ||
71 | (read(mapped_status) & (1 << clk->enable_bit)) && i; | ||
72 | i--) | ||
73 | cpu_relax(); | ||
74 | if (!i) { | ||
75 | pr_err("cpg: failed to enable %p[%d]\n", | ||
76 | clk->enable_reg, clk->enable_bit); | ||
77 | return -ETIMEDOUT; | ||
78 | } | ||
79 | } | ||
42 | return 0; | 80 | return 0; |
43 | } | 81 | } |
44 | 82 | ||
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 5f88d767671e..2d51912a6e40 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
@@ -143,7 +143,7 @@ config RCAR_THERMAL | |||
143 | 143 | ||
144 | config KIRKWOOD_THERMAL | 144 | config KIRKWOOD_THERMAL |
145 | tristate "Temperature sensor on Marvell Kirkwood SoCs" | 145 | tristate "Temperature sensor on Marvell Kirkwood SoCs" |
146 | depends on ARCH_KIRKWOOD | 146 | depends on ARCH_KIRKWOOD || MACH_KIRKWOOD |
147 | depends on OF | 147 | depends on OF |
148 | help | 148 | help |
149 | Support for the Kirkwood thermal sensor driver into the Linux thermal | 149 | Support for the Kirkwood thermal sensor driver into the Linux thermal |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2577d67bacb2..2e6d8ddc4425 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -1024,7 +1024,7 @@ config SERIAL_SGI_IOC3 | |||
1024 | 1024 | ||
1025 | config SERIAL_MSM | 1025 | config SERIAL_MSM |
1026 | bool "MSM on-chip serial port support" | 1026 | bool "MSM on-chip serial port support" |
1027 | depends on ARCH_MSM | 1027 | depends on ARCH_MSM || ARCH_QCOM |
1028 | select SERIAL_CORE | 1028 | select SERIAL_CORE |
1029 | 1029 | ||
1030 | config SERIAL_MSM_CONSOLE | 1030 | config SERIAL_MSM_CONSOLE |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0c6048d5c9a3..74ec8fc5cc03 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -301,7 +301,7 @@ config DAVINCI_WATCHDOG | |||
301 | 301 | ||
302 | config ORION_WATCHDOG | 302 | config ORION_WATCHDOG |
303 | tristate "Orion watchdog" | 303 | tristate "Orion watchdog" |
304 | depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE | 304 | depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE || ARCH_MVEBU |
305 | select WATCHDOG_CORE | 305 | select WATCHDOG_CORE |
306 | help | 306 | help |
307 | Say Y here if to include support for the watchdog timer | 307 | Say Y here if to include support for the watchdog timer |
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 498163497c1c..9b3c41d18703 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c | |||
@@ -18,101 +18,204 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
21 | #include <linux/interrupt.h> | ||
21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <mach/bridge-regs.h> | 26 | #include <linux/of_device.h> |
27 | |||
28 | /* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */ | ||
29 | #define ORION_RSTOUT_MASK_OFFSET 0x20108 | ||
30 | |||
31 | /* Internal registers can be configured at any 1 MiB aligned address */ | ||
32 | #define INTERNAL_REGS_MASK ~(SZ_1M - 1) | ||
27 | 33 | ||
28 | /* | 34 | /* |
29 | * Watchdog timer block registers. | 35 | * Watchdog timer block registers. |
30 | */ | 36 | */ |
31 | #define TIMER_CTRL 0x0000 | 37 | #define TIMER_CTRL 0x0000 |
32 | #define WDT_EN 0x0010 | 38 | #define TIMER_A370_STATUS 0x04 |
33 | #define WDT_VAL 0x0024 | ||
34 | 39 | ||
35 | #define WDT_MAX_CYCLE_COUNT 0xffffffff | 40 | #define WDT_MAX_CYCLE_COUNT 0xffffffff |
36 | #define WDT_IN_USE 0 | ||
37 | #define WDT_OK_TO_CLOSE 1 | ||
38 | 41 | ||
39 | #define WDT_RESET_OUT_EN BIT(1) | 42 | #define WDT_A370_RATIO_MASK(v) ((v) << 16) |
40 | #define WDT_INT_REQ BIT(3) | 43 | #define WDT_A370_RATIO_SHIFT 5 |
44 | #define WDT_A370_RATIO (1 << WDT_A370_RATIO_SHIFT) | ||
45 | |||
46 | #define WDT_AXP_FIXED_ENABLE_BIT BIT(10) | ||
47 | #define WDT_A370_EXPIRED BIT(31) | ||
41 | 48 | ||
42 | static bool nowayout = WATCHDOG_NOWAYOUT; | 49 | static bool nowayout = WATCHDOG_NOWAYOUT; |
43 | static int heartbeat = -1; /* module parameter (seconds) */ | 50 | static int heartbeat = -1; /* module parameter (seconds) */ |
44 | static unsigned int wdt_max_duration; /* (seconds) */ | ||
45 | static struct clk *clk; | ||
46 | static unsigned int wdt_tclk; | ||
47 | static void __iomem *wdt_reg; | ||
48 | static DEFINE_SPINLOCK(wdt_lock); | ||
49 | 51 | ||
50 | static int orion_wdt_ping(struct watchdog_device *wdt_dev) | 52 | struct orion_watchdog; |
53 | |||
54 | struct orion_watchdog_data { | ||
55 | int wdt_counter_offset; | ||
56 | int wdt_enable_bit; | ||
57 | int rstout_enable_bit; | ||
58 | int (*clock_init)(struct platform_device *, | ||
59 | struct orion_watchdog *); | ||
60 | int (*start)(struct watchdog_device *); | ||
61 | }; | ||
62 | |||
63 | struct orion_watchdog { | ||
64 | struct watchdog_device wdt; | ||
65 | void __iomem *reg; | ||
66 | void __iomem *rstout; | ||
67 | unsigned long clk_rate; | ||
68 | struct clk *clk; | ||
69 | const struct orion_watchdog_data *data; | ||
70 | }; | ||
71 | |||
72 | static int orion_wdt_clock_init(struct platform_device *pdev, | ||
73 | struct orion_watchdog *dev) | ||
51 | { | 74 | { |
52 | spin_lock(&wdt_lock); | 75 | int ret; |
53 | 76 | ||
54 | /* Reload watchdog duration */ | 77 | dev->clk = clk_get(&pdev->dev, NULL); |
55 | writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL); | 78 | if (IS_ERR(dev->clk)) |
79 | return PTR_ERR(dev->clk); | ||
80 | ret = clk_prepare_enable(dev->clk); | ||
81 | if (ret) { | ||
82 | clk_put(dev->clk); | ||
83 | return ret; | ||
84 | } | ||
56 | 85 | ||
57 | spin_unlock(&wdt_lock); | 86 | dev->clk_rate = clk_get_rate(dev->clk); |
58 | return 0; | 87 | return 0; |
59 | } | 88 | } |
60 | 89 | ||
61 | static int orion_wdt_start(struct watchdog_device *wdt_dev) | 90 | static int armada370_wdt_clock_init(struct platform_device *pdev, |
91 | struct orion_watchdog *dev) | ||
62 | { | 92 | { |
63 | u32 reg; | 93 | int ret; |
64 | 94 | ||
65 | spin_lock(&wdt_lock); | 95 | dev->clk = clk_get(&pdev->dev, NULL); |
96 | if (IS_ERR(dev->clk)) | ||
97 | return PTR_ERR(dev->clk); | ||
98 | ret = clk_prepare_enable(dev->clk); | ||
99 | if (ret) { | ||
100 | clk_put(dev->clk); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | /* Setup watchdog input clock */ | ||
105 | atomic_io_modify(dev->reg + TIMER_CTRL, | ||
106 | WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT), | ||
107 | WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT)); | ||
108 | |||
109 | dev->clk_rate = clk_get_rate(dev->clk) / WDT_A370_RATIO; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int armadaxp_wdt_clock_init(struct platform_device *pdev, | ||
114 | struct orion_watchdog *dev) | ||
115 | { | ||
116 | int ret; | ||
117 | |||
118 | dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed"); | ||
119 | if (IS_ERR(dev->clk)) | ||
120 | return PTR_ERR(dev->clk); | ||
121 | ret = clk_prepare_enable(dev->clk); | ||
122 | if (ret) { | ||
123 | clk_put(dev->clk); | ||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | /* Enable the fixed watchdog clock input */ | ||
128 | atomic_io_modify(dev->reg + TIMER_CTRL, | ||
129 | WDT_AXP_FIXED_ENABLE_BIT, | ||
130 | WDT_AXP_FIXED_ENABLE_BIT); | ||
131 | |||
132 | dev->clk_rate = clk_get_rate(dev->clk); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int orion_wdt_ping(struct watchdog_device *wdt_dev) | ||
137 | { | ||
138 | struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); | ||
139 | /* Reload watchdog duration */ | ||
140 | writel(dev->clk_rate * wdt_dev->timeout, | ||
141 | dev->reg + dev->data->wdt_counter_offset); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int armada370_start(struct watchdog_device *wdt_dev) | ||
146 | { | ||
147 | struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); | ||
66 | 148 | ||
67 | /* Set watchdog duration */ | 149 | /* Set watchdog duration */ |
68 | writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL); | 150 | writel(dev->clk_rate * wdt_dev->timeout, |
151 | dev->reg + dev->data->wdt_counter_offset); | ||
69 | 152 | ||
70 | /* Clear watchdog timer interrupt */ | 153 | /* Clear the watchdog expiration bit */ |
71 | writel(~WDT_INT_REQ, BRIDGE_CAUSE); | 154 | atomic_io_modify(dev->reg + TIMER_A370_STATUS, WDT_A370_EXPIRED, 0); |
72 | 155 | ||
73 | /* Enable watchdog timer */ | 156 | /* Enable watchdog timer */ |
74 | reg = readl(wdt_reg + TIMER_CTRL); | 157 | atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, |
75 | reg |= WDT_EN; | 158 | dev->data->wdt_enable_bit); |
76 | writel(reg, wdt_reg + TIMER_CTRL); | 159 | |
160 | atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit, | ||
161 | dev->data->rstout_enable_bit); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int orion_start(struct watchdog_device *wdt_dev) | ||
166 | { | ||
167 | struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); | ||
168 | |||
169 | /* Set watchdog duration */ | ||
170 | writel(dev->clk_rate * wdt_dev->timeout, | ||
171 | dev->reg + dev->data->wdt_counter_offset); | ||
172 | |||
173 | /* Enable watchdog timer */ | ||
174 | atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, | ||
175 | dev->data->wdt_enable_bit); | ||
77 | 176 | ||
78 | /* Enable reset on watchdog */ | 177 | /* Enable reset on watchdog */ |
79 | reg = readl(RSTOUTn_MASK); | 178 | atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit, |
80 | reg |= WDT_RESET_OUT_EN; | 179 | dev->data->rstout_enable_bit); |
81 | writel(reg, RSTOUTn_MASK); | ||
82 | 180 | ||
83 | spin_unlock(&wdt_lock); | ||
84 | return 0; | 181 | return 0; |
85 | } | 182 | } |
86 | 183 | ||
87 | static int orion_wdt_stop(struct watchdog_device *wdt_dev) | 184 | static int orion_wdt_start(struct watchdog_device *wdt_dev) |
88 | { | 185 | { |
89 | u32 reg; | 186 | struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); |
90 | 187 | ||
91 | spin_lock(&wdt_lock); | 188 | /* There are some per-SoC quirks to handle */ |
189 | return dev->data->start(wdt_dev); | ||
190 | } | ||
191 | |||
192 | static int orion_wdt_stop(struct watchdog_device *wdt_dev) | ||
193 | { | ||
194 | struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); | ||
92 | 195 | ||
93 | /* Disable reset on watchdog */ | 196 | /* Disable reset on watchdog */ |
94 | reg = readl(RSTOUTn_MASK); | 197 | atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit, 0); |
95 | reg &= ~WDT_RESET_OUT_EN; | ||
96 | writel(reg, RSTOUTn_MASK); | ||
97 | 198 | ||
98 | /* Disable watchdog timer */ | 199 | /* Disable watchdog timer */ |
99 | reg = readl(wdt_reg + TIMER_CTRL); | 200 | atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, 0); |
100 | reg &= ~WDT_EN; | ||
101 | writel(reg, wdt_reg + TIMER_CTRL); | ||
102 | 201 | ||
103 | spin_unlock(&wdt_lock); | ||
104 | return 0; | 202 | return 0; |
105 | } | 203 | } |
106 | 204 | ||
107 | static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev) | 205 | static int orion_wdt_enabled(struct orion_watchdog *dev) |
108 | { | 206 | { |
109 | unsigned int time_left; | 207 | bool enabled, running; |
208 | |||
209 | enabled = readl(dev->rstout) & dev->data->rstout_enable_bit; | ||
210 | running = readl(dev->reg + TIMER_CTRL) & dev->data->wdt_enable_bit; | ||
110 | 211 | ||
111 | spin_lock(&wdt_lock); | 212 | return enabled && running; |
112 | time_left = readl(wdt_reg + WDT_VAL) / wdt_tclk; | 213 | } |
113 | spin_unlock(&wdt_lock); | ||
114 | 214 | ||
115 | return time_left; | 215 | static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev) |
216 | { | ||
217 | struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); | ||
218 | return readl(dev->reg + dev->data->wdt_counter_offset) / dev->clk_rate; | ||
116 | } | 219 | } |
117 | 220 | ||
118 | static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev, | 221 | static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev, |
@@ -136,68 +239,188 @@ static const struct watchdog_ops orion_wdt_ops = { | |||
136 | .get_timeleft = orion_wdt_get_timeleft, | 239 | .get_timeleft = orion_wdt_get_timeleft, |
137 | }; | 240 | }; |
138 | 241 | ||
139 | static struct watchdog_device orion_wdt = { | 242 | static irqreturn_t orion_wdt_irq(int irq, void *devid) |
140 | .info = &orion_wdt_info, | 243 | { |
141 | .ops = &orion_wdt_ops, | 244 | panic("Watchdog Timeout"); |
142 | .min_timeout = 1, | 245 | return IRQ_HANDLED; |
246 | } | ||
247 | |||
248 | /* | ||
249 | * The original devicetree binding for this driver specified only | ||
250 | * one memory resource, so in order to keep DT backwards compatibility | ||
251 | * we try to fallback to a hardcoded register address, if the resource | ||
252 | * is missing from the devicetree. | ||
253 | */ | ||
254 | static void __iomem *orion_wdt_ioremap_rstout(struct platform_device *pdev, | ||
255 | phys_addr_t internal_regs) | ||
256 | { | ||
257 | struct resource *res; | ||
258 | phys_addr_t rstout; | ||
259 | |||
260 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
261 | if (res) | ||
262 | return devm_ioremap(&pdev->dev, res->start, | ||
263 | resource_size(res)); | ||
264 | |||
265 | /* This workaround works only for "orion-wdt", DT-enabled */ | ||
266 | if (!of_device_is_compatible(pdev->dev.of_node, "marvell,orion-wdt")) | ||
267 | return NULL; | ||
268 | |||
269 | rstout = internal_regs + ORION_RSTOUT_MASK_OFFSET; | ||
270 | |||
271 | WARN(1, FW_BUG "falling back to harcoded RSTOUT reg %pa\n", &rstout); | ||
272 | return devm_ioremap(&pdev->dev, rstout, 0x4); | ||
273 | } | ||
274 | |||
275 | static const struct orion_watchdog_data orion_data = { | ||
276 | .rstout_enable_bit = BIT(1), | ||
277 | .wdt_enable_bit = BIT(4), | ||
278 | .wdt_counter_offset = 0x24, | ||
279 | .clock_init = orion_wdt_clock_init, | ||
280 | .start = orion_start, | ||
281 | }; | ||
282 | |||
283 | static const struct orion_watchdog_data armada370_data = { | ||
284 | .rstout_enable_bit = BIT(8), | ||
285 | .wdt_enable_bit = BIT(8), | ||
286 | .wdt_counter_offset = 0x34, | ||
287 | .clock_init = armada370_wdt_clock_init, | ||
288 | .start = armada370_start, | ||
143 | }; | 289 | }; |
144 | 290 | ||
291 | static const struct orion_watchdog_data armadaxp_data = { | ||
292 | .rstout_enable_bit = BIT(8), | ||
293 | .wdt_enable_bit = BIT(8), | ||
294 | .wdt_counter_offset = 0x34, | ||
295 | .clock_init = armadaxp_wdt_clock_init, | ||
296 | .start = armada370_start, | ||
297 | }; | ||
298 | |||
299 | static const struct of_device_id orion_wdt_of_match_table[] = { | ||
300 | { | ||
301 | .compatible = "marvell,orion-wdt", | ||
302 | .data = &orion_data, | ||
303 | }, | ||
304 | { | ||
305 | .compatible = "marvell,armada-370-wdt", | ||
306 | .data = &armada370_data, | ||
307 | }, | ||
308 | { | ||
309 | .compatible = "marvell,armada-xp-wdt", | ||
310 | .data = &armadaxp_data, | ||
311 | }, | ||
312 | {}, | ||
313 | }; | ||
314 | MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table); | ||
315 | |||
145 | static int orion_wdt_probe(struct platform_device *pdev) | 316 | static int orion_wdt_probe(struct platform_device *pdev) |
146 | { | 317 | { |
318 | struct orion_watchdog *dev; | ||
319 | const struct of_device_id *match; | ||
320 | unsigned int wdt_max_duration; /* (seconds) */ | ||
147 | struct resource *res; | 321 | struct resource *res; |
148 | int ret; | 322 | int ret, irq; |
149 | 323 | ||
150 | clk = devm_clk_get(&pdev->dev, NULL); | 324 | dev = devm_kzalloc(&pdev->dev, sizeof(struct orion_watchdog), |
151 | if (IS_ERR(clk)) { | 325 | GFP_KERNEL); |
152 | dev_err(&pdev->dev, "Orion Watchdog missing clock\n"); | 326 | if (!dev) |
153 | return -ENODEV; | 327 | return -ENOMEM; |
154 | } | 328 | |
155 | clk_prepare_enable(clk); | 329 | match = of_match_device(orion_wdt_of_match_table, &pdev->dev); |
156 | wdt_tclk = clk_get_rate(clk); | 330 | if (!match) |
331 | /* Default legacy match */ | ||
332 | match = &orion_wdt_of_match_table[0]; | ||
333 | |||
334 | dev->wdt.info = &orion_wdt_info; | ||
335 | dev->wdt.ops = &orion_wdt_ops; | ||
336 | dev->wdt.min_timeout = 1; | ||
337 | dev->data = match->data; | ||
157 | 338 | ||
158 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 339 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
159 | if (!res) | 340 | if (!res) |
160 | return -ENODEV; | 341 | return -ENODEV; |
161 | wdt_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
162 | if (!wdt_reg) | ||
163 | return -ENOMEM; | ||
164 | 342 | ||
165 | wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; | 343 | dev->reg = devm_ioremap(&pdev->dev, res->start, |
344 | resource_size(res)); | ||
345 | if (!dev->reg) | ||
346 | return -ENOMEM; | ||
166 | 347 | ||
167 | orion_wdt.timeout = wdt_max_duration; | 348 | dev->rstout = orion_wdt_ioremap_rstout(pdev, res->start & |
168 | orion_wdt.max_timeout = wdt_max_duration; | 349 | INTERNAL_REGS_MASK); |
169 | watchdog_init_timeout(&orion_wdt, heartbeat, &pdev->dev); | 350 | if (!dev->rstout) |
351 | return -ENODEV; | ||
170 | 352 | ||
171 | watchdog_set_nowayout(&orion_wdt, nowayout); | 353 | ret = dev->data->clock_init(pdev, dev); |
172 | ret = watchdog_register_device(&orion_wdt); | ||
173 | if (ret) { | 354 | if (ret) { |
174 | clk_disable_unprepare(clk); | 355 | dev_err(&pdev->dev, "cannot initialize clock\n"); |
175 | return ret; | 356 | return ret; |
176 | } | 357 | } |
177 | 358 | ||
359 | wdt_max_duration = WDT_MAX_CYCLE_COUNT / dev->clk_rate; | ||
360 | |||
361 | dev->wdt.timeout = wdt_max_duration; | ||
362 | dev->wdt.max_timeout = wdt_max_duration; | ||
363 | watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev); | ||
364 | |||
365 | platform_set_drvdata(pdev, &dev->wdt); | ||
366 | watchdog_set_drvdata(&dev->wdt, dev); | ||
367 | |||
368 | /* | ||
369 | * Let's make sure the watchdog is fully stopped, unless it's | ||
370 | * explicitly enabled. This may be the case if the module was | ||
371 | * removed and re-insterted, or if the bootloader explicitly | ||
372 | * set a running watchdog before booting the kernel. | ||
373 | */ | ||
374 | if (!orion_wdt_enabled(dev)) | ||
375 | orion_wdt_stop(&dev->wdt); | ||
376 | |||
377 | /* Request the IRQ only after the watchdog is disabled */ | ||
378 | irq = platform_get_irq(pdev, 0); | ||
379 | if (irq > 0) { | ||
380 | /* | ||
381 | * Not all supported platforms specify an interrupt for the | ||
382 | * watchdog, so let's make it optional. | ||
383 | */ | ||
384 | ret = devm_request_irq(&pdev->dev, irq, orion_wdt_irq, 0, | ||
385 | pdev->name, dev); | ||
386 | if (ret < 0) { | ||
387 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
388 | goto disable_clk; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | watchdog_set_nowayout(&dev->wdt, nowayout); | ||
393 | ret = watchdog_register_device(&dev->wdt); | ||
394 | if (ret) | ||
395 | goto disable_clk; | ||
396 | |||
178 | pr_info("Initial timeout %d sec%s\n", | 397 | pr_info("Initial timeout %d sec%s\n", |
179 | orion_wdt.timeout, nowayout ? ", nowayout" : ""); | 398 | dev->wdt.timeout, nowayout ? ", nowayout" : ""); |
180 | return 0; | 399 | return 0; |
400 | |||
401 | disable_clk: | ||
402 | clk_disable_unprepare(dev->clk); | ||
403 | clk_put(dev->clk); | ||
404 | return ret; | ||
181 | } | 405 | } |
182 | 406 | ||
183 | static int orion_wdt_remove(struct platform_device *pdev) | 407 | static int orion_wdt_remove(struct platform_device *pdev) |
184 | { | 408 | { |
185 | watchdog_unregister_device(&orion_wdt); | 409 | struct watchdog_device *wdt_dev = platform_get_drvdata(pdev); |
186 | clk_disable_unprepare(clk); | 410 | struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev); |
411 | |||
412 | watchdog_unregister_device(wdt_dev); | ||
413 | clk_disable_unprepare(dev->clk); | ||
414 | clk_put(dev->clk); | ||
187 | return 0; | 415 | return 0; |
188 | } | 416 | } |
189 | 417 | ||
190 | static void orion_wdt_shutdown(struct platform_device *pdev) | 418 | static void orion_wdt_shutdown(struct platform_device *pdev) |
191 | { | 419 | { |
192 | orion_wdt_stop(&orion_wdt); | 420 | struct watchdog_device *wdt_dev = platform_get_drvdata(pdev); |
421 | orion_wdt_stop(wdt_dev); | ||
193 | } | 422 | } |
194 | 423 | ||
195 | static const struct of_device_id orion_wdt_of_match_table[] = { | ||
196 | { .compatible = "marvell,orion-wdt", }, | ||
197 | {}, | ||
198 | }; | ||
199 | MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table); | ||
200 | |||
201 | static struct platform_driver orion_wdt_driver = { | 424 | static struct platform_driver orion_wdt_driver = { |
202 | .probe = orion_wdt_probe, | 425 | .probe = orion_wdt_probe, |
203 | .remove = orion_wdt_remove, | 426 | .remove = orion_wdt_remove, |
diff --git a/include/dt-bindings/clock/bcm281xx.h b/include/dt-bindings/clock/bcm281xx.h new file mode 100644 index 000000000000..e0096940886d --- /dev/null +++ b/include/dt-bindings/clock/bcm281xx.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * Copyright 2013 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation version 2. | ||
8 | * | ||
9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
10 | * kind, whether express or implied; without even the implied warranty | ||
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _CLOCK_BCM281XX_H | ||
16 | #define _CLOCK_BCM281XX_H | ||
17 | |||
18 | /* | ||
19 | * This file defines the values used to specify clocks provided by | ||
20 | * the clock control units (CCUs) on Broadcom BCM281XX family SoCs. | ||
21 | */ | ||
22 | |||
23 | /* root CCU clock ids */ | ||
24 | |||
25 | #define BCM281XX_ROOT_CCU_FRAC_1M 0 | ||
26 | #define BCM281XX_ROOT_CCU_CLOCK_COUNT 1 | ||
27 | |||
28 | /* aon CCU clock ids */ | ||
29 | |||
30 | #define BCM281XX_AON_CCU_HUB_TIMER 0 | ||
31 | #define BCM281XX_AON_CCU_PMU_BSC 1 | ||
32 | #define BCM281XX_AON_CCU_PMU_BSC_VAR 2 | ||
33 | #define BCM281XX_AON_CCU_CLOCK_COUNT 3 | ||
34 | |||
35 | /* hub CCU clock ids */ | ||
36 | |||
37 | #define BCM281XX_HUB_CCU_TMON_1M 0 | ||
38 | #define BCM281XX_HUB_CCU_CLOCK_COUNT 1 | ||
39 | |||
40 | /* master CCU clock ids */ | ||
41 | |||
42 | #define BCM281XX_MASTER_CCU_SDIO1 0 | ||
43 | #define BCM281XX_MASTER_CCU_SDIO2 1 | ||
44 | #define BCM281XX_MASTER_CCU_SDIO3 2 | ||
45 | #define BCM281XX_MASTER_CCU_SDIO4 3 | ||
46 | #define BCM281XX_MASTER_CCU_USB_IC 4 | ||
47 | #define BCM281XX_MASTER_CCU_HSIC2_48M 5 | ||
48 | #define BCM281XX_MASTER_CCU_HSIC2_12M 6 | ||
49 | #define BCM281XX_MASTER_CCU_CLOCK_COUNT 7 | ||
50 | |||
51 | /* slave CCU clock ids */ | ||
52 | |||
53 | #define BCM281XX_SLAVE_CCU_UARTB 0 | ||
54 | #define BCM281XX_SLAVE_CCU_UARTB2 1 | ||
55 | #define BCM281XX_SLAVE_CCU_UARTB3 2 | ||
56 | #define BCM281XX_SLAVE_CCU_UARTB4 3 | ||
57 | #define BCM281XX_SLAVE_CCU_SSP0 4 | ||
58 | #define BCM281XX_SLAVE_CCU_SSP2 5 | ||
59 | #define BCM281XX_SLAVE_CCU_BSC1 6 | ||
60 | #define BCM281XX_SLAVE_CCU_BSC2 7 | ||
61 | #define BCM281XX_SLAVE_CCU_BSC3 8 | ||
62 | #define BCM281XX_SLAVE_CCU_PWM 9 | ||
63 | #define BCM281XX_SLAVE_CCU_CLOCK_COUNT 10 | ||
64 | |||
65 | #endif /* _CLOCK_BCM281XX_H */ | ||
diff --git a/include/dt-bindings/clock/r8a7790-clock.h b/include/dt-bindings/clock/r8a7790-clock.h index 859e9be511d9..6548a5fbcf4a 100644 --- a/include/dt-bindings/clock/r8a7790-clock.h +++ b/include/dt-bindings/clock/r8a7790-clock.h | |||
@@ -46,8 +46,8 @@ | |||
46 | #define R8A7790_CLK_MSIOF1 8 | 46 | #define R8A7790_CLK_MSIOF1 8 |
47 | #define R8A7790_CLK_MSIOF3 15 | 47 | #define R8A7790_CLK_MSIOF3 15 |
48 | #define R8A7790_CLK_SCIFB2 16 | 48 | #define R8A7790_CLK_SCIFB2 16 |
49 | #define R8A7790_CLK_SYS_DMAC0 18 | 49 | #define R8A7790_CLK_SYS_DMAC1 18 |
50 | #define R8A7790_CLK_SYS_DMAC1 19 | 50 | #define R8A7790_CLK_SYS_DMAC0 19 |
51 | 51 | ||
52 | /* MSTP3 */ | 52 | /* MSTP3 */ |
53 | #define R8A7790_CLK_TPU0 4 | 53 | #define R8A7790_CLK_TPU0 4 |
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 0ceb389dba6c..7ed92d0560d5 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h | |||
@@ -93,6 +93,11 @@ int gic_get_cpu_id(unsigned int cpu); | |||
93 | void gic_migrate_target(unsigned int new_cpu_id); | 93 | void gic_migrate_target(unsigned int new_cpu_id); |
94 | unsigned long gic_get_sgir_physaddr(void); | 94 | unsigned long gic_get_sgir_physaddr(void); |
95 | 95 | ||
96 | extern const struct irq_domain_ops *gic_routable_irq_domain_ops; | ||
97 | static inline void __init register_routable_domain_ops | ||
98 | (const struct irq_domain_ops *ops) | ||
99 | { | ||
100 | gic_routable_irq_domain_ops = ops; | ||
101 | } | ||
96 | #endif /* __ASSEMBLY */ | 102 | #endif /* __ASSEMBLY */ |
97 | |||
98 | #endif | 103 | #endif |
diff --git a/include/linux/irqchip/arm-vic.h b/include/linux/irqchip/arm-vic.h index e3c82dc95756..ba46c794b4e5 100644 --- a/include/linux/irqchip/arm-vic.h +++ b/include/linux/irqchip/arm-vic.h | |||
@@ -29,8 +29,10 @@ | |||
29 | struct device_node; | 29 | struct device_node; |
30 | struct pt_regs; | 30 | struct pt_regs; |
31 | 31 | ||
32 | void __vic_init(void __iomem *base, int irq_start, u32 vic_sources, | 32 | void __vic_init(void __iomem *base, int parent_irq, int irq_start, |
33 | u32 resume_sources, struct device_node *node); | 33 | u32 vic_sources, u32 resume_sources, struct device_node *node); |
34 | void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); | 34 | void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); |
35 | int vic_init_cascaded(void __iomem *base, unsigned int parent_irq, | ||
36 | u32 vic_sources, u32 resume_sources); | ||
35 | 37 | ||
36 | #endif | 38 | #endif |
diff --git a/include/linux/irqchip/irq-crossbar.h b/include/linux/irqchip/irq-crossbar.h new file mode 100644 index 000000000000..e5537b81df8d --- /dev/null +++ b/include/linux/irqchip/irq-crossbar.h | |||
@@ -0,0 +1,11 @@ | |||
1 | /* | ||
2 | * drivers/irqchip/irq-crossbar.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | int irqcrossbar_init(void); | ||
diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h index 280edac9d0a5..addd48cac625 100644 --- a/include/linux/platform_data/clk-integrator.h +++ b/include/linux/platform_data/clk-integrator.h | |||
@@ -1,3 +1,2 @@ | |||
1 | void integrator_clk_init(bool is_cp); | ||
2 | void integrator_impd1_clk_init(void __iomem *base, unsigned int id); | 1 | void integrator_impd1_clk_init(void __iomem *base, unsigned int id); |
3 | void integrator_impd1_clk_exit(unsigned int id); | 2 | void integrator_impd1_clk_exit(unsigned int id); |
diff --git a/include/linux/platform_data/mtd-davinci-aemif.h b/include/linux/platform_data/mtd-davinci-aemif.h index 05b293443097..97948ac2bb9b 100644 --- a/include/linux/platform_data/mtd-davinci-aemif.h +++ b/include/linux/platform_data/mtd-davinci-aemif.h | |||
@@ -10,6 +10,8 @@ | |||
10 | #ifndef _MACH_DAVINCI_AEMIF_H | 10 | #ifndef _MACH_DAVINCI_AEMIF_H |
11 | #define _MACH_DAVINCI_AEMIF_H | 11 | #define _MACH_DAVINCI_AEMIF_H |
12 | 12 | ||
13 | #include <linux/platform_device.h> | ||
14 | |||
13 | #define NRCSR_OFFSET 0x00 | 15 | #define NRCSR_OFFSET 0x00 |
14 | #define AWCCR_OFFSET 0x04 | 16 | #define AWCCR_OFFSET 0x04 |
15 | #define A1CR_OFFSET 0x10 | 17 | #define A1CR_OFFSET 0x10 |
@@ -31,6 +33,5 @@ struct davinci_aemif_timing { | |||
31 | u8 ta; | 33 | u8 ta; |
32 | }; | 34 | }; |
33 | 35 | ||
34 | int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, | 36 | int davinci_aemif_setup(struct platform_device *pdev); |
35 | void __iomem *base, unsigned cs); | ||
36 | #endif | 37 | #endif |
diff --git a/include/linux/reset.h b/include/linux/reset.h index 6082247feab1..c0eda5023d74 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h | |||
@@ -4,6 +4,8 @@ | |||
4 | struct device; | 4 | struct device; |
5 | struct reset_control; | 5 | struct reset_control; |
6 | 6 | ||
7 | #ifdef CONFIG_RESET_CONTROLLER | ||
8 | |||
7 | int reset_control_reset(struct reset_control *rstc); | 9 | int reset_control_reset(struct reset_control *rstc); |
8 | int reset_control_assert(struct reset_control *rstc); | 10 | int reset_control_assert(struct reset_control *rstc); |
9 | int reset_control_deassert(struct reset_control *rstc); | 11 | int reset_control_deassert(struct reset_control *rstc); |
@@ -12,6 +14,67 @@ struct reset_control *reset_control_get(struct device *dev, const char *id); | |||
12 | void reset_control_put(struct reset_control *rstc); | 14 | void reset_control_put(struct reset_control *rstc); |
13 | struct reset_control *devm_reset_control_get(struct device *dev, const char *id); | 15 | struct reset_control *devm_reset_control_get(struct device *dev, const char *id); |
14 | 16 | ||
15 | int device_reset(struct device *dev); | 17 | int __must_check device_reset(struct device *dev); |
18 | |||
19 | static inline int device_reset_optional(struct device *dev) | ||
20 | { | ||
21 | return device_reset(dev); | ||
22 | } | ||
23 | |||
24 | static inline struct reset_control *reset_control_get_optional( | ||
25 | struct device *dev, const char *id) | ||
26 | { | ||
27 | return reset_control_get(dev, id); | ||
28 | } | ||
29 | |||
30 | static inline struct reset_control *devm_reset_control_get_optional( | ||
31 | struct device *dev, const char *id) | ||
32 | { | ||
33 | return devm_reset_control_get(dev, id); | ||
34 | } | ||
35 | |||
36 | #else | ||
37 | |||
38 | static inline int reset_control_reset(struct reset_control *rstc) | ||
39 | { | ||
40 | WARN_ON(1); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static inline int reset_control_assert(struct reset_control *rstc) | ||
45 | { | ||
46 | WARN_ON(1); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static inline int reset_control_deassert(struct reset_control *rstc) | ||
51 | { | ||
52 | WARN_ON(1); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static inline void reset_control_put(struct reset_control *rstc) | ||
57 | { | ||
58 | WARN_ON(1); | ||
59 | } | ||
60 | |||
61 | static inline int device_reset_optional(struct device *dev) | ||
62 | { | ||
63 | return -ENOSYS; | ||
64 | } | ||
65 | |||
66 | static inline struct reset_control *reset_control_get_optional( | ||
67 | struct device *dev, const char *id) | ||
68 | { | ||
69 | return ERR_PTR(-ENOSYS); | ||
70 | } | ||
71 | |||
72 | static inline struct reset_control *devm_reset_control_get_optional( | ||
73 | struct device *dev, const char *id) | ||
74 | { | ||
75 | return ERR_PTR(-ENOSYS); | ||
76 | } | ||
77 | |||
78 | #endif /* CONFIG_RESET_CONTROLLER */ | ||
16 | 79 | ||
17 | #endif | 80 | #endif |
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 60c72395ec6b..1f208b2a1ed6 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h | |||
@@ -52,6 +52,7 @@ struct clk { | |||
52 | unsigned long flags; | 52 | unsigned long flags; |
53 | 53 | ||
54 | void __iomem *enable_reg; | 54 | void __iomem *enable_reg; |
55 | void __iomem *status_reg; | ||
55 | unsigned int enable_bit; | 56 | unsigned int enable_bit; |
56 | void __iomem *mapped_reg; | 57 | void __iomem *mapped_reg; |
57 | 58 | ||
@@ -116,22 +117,26 @@ long clk_round_parent(struct clk *clk, unsigned long target, | |||
116 | unsigned long *best_freq, unsigned long *parent_freq, | 117 | unsigned long *best_freq, unsigned long *parent_freq, |
117 | unsigned int div_min, unsigned int div_max); | 118 | unsigned int div_min, unsigned int div_max); |
118 | 119 | ||
119 | #define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _flags) \ | 120 | #define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _status_reg, _flags) \ |
120 | { \ | 121 | { \ |
121 | .parent = _parent, \ | 122 | .parent = _parent, \ |
122 | .enable_reg = (void __iomem *)_enable_reg, \ | 123 | .enable_reg = (void __iomem *)_enable_reg, \ |
123 | .enable_bit = _enable_bit, \ | 124 | .enable_bit = _enable_bit, \ |
125 | .status_reg = _status_reg, \ | ||
124 | .flags = _flags, \ | 126 | .flags = _flags, \ |
125 | } | 127 | } |
126 | 128 | ||
127 | #define SH_CLK_MSTP32(_p, _r, _b, _f) \ | 129 | #define SH_CLK_MSTP32(_p, _r, _b, _f) \ |
128 | SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_32BIT) | 130 | SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_32BIT) |
129 | 131 | ||
130 | #define SH_CLK_MSTP16(_p, _r, _b, _f) \ | 132 | #define SH_CLK_MSTP32_STS(_p, _r, _b, _s, _f) \ |
131 | SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_16BIT) | 133 | SH_CLK_MSTP(_p, _r, _b, _s, _f | CLK_ENABLE_REG_32BIT) |
132 | 134 | ||
133 | #define SH_CLK_MSTP8(_p, _r, _b, _f) \ | 135 | #define SH_CLK_MSTP16(_p, _r, _b, _f) \ |
134 | SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_8BIT) | 136 | SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_16BIT) |
137 | |||
138 | #define SH_CLK_MSTP8(_p, _r, _b, _f) \ | ||
139 | SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_8BIT) | ||
135 | 140 | ||
136 | int sh_clk_mstp_register(struct clk *clks, int nr); | 141 | int sh_clk_mstp_register(struct clk *clks, int nr); |
137 | 142 | ||
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 49f8437665de..06f4e8aa93ae 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SND_KIRKWOOD_SOC | 1 | config SND_KIRKWOOD_SOC |
2 | tristate "SoC Audio for the Marvell Kirkwood and Dove chips" | 2 | tristate "SoC Audio for the Marvell Kirkwood and Dove chips" |
3 | depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST | 3 | depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU || MACH_KIRKWOOD || COMPILE_TEST |
4 | help | 4 | help |
5 | Say Y or M if you want to add support for codecs attached to | 5 | Say Y or M if you want to add support for codecs attached to |
6 | the Kirkwood I2S interface. You will also need to select the | 6 | the Kirkwood I2S interface. You will also need to select the |