Commit 87c7662bea584d5e495e97a59c20b9abaac4eee8
Exists in
master
and in
13 other branches
Merge tag 'dt-for-linus' of git://git.secretlab.ca/git/linux
Pull devicetree bug fixes from Grant Likely: "These are some important bug fixes that need to get into v3.15. This branch contains a pair of important bug fixes for the DT code: - Fix some incorrect binding property names before they enter common usage - Fix bug where some platform devices will be unable to get their interrupt number when they depend on an interrupt controller that is not available at device creation time. This is a problem causing mainline to fail on a number of ARM platforms" * tag 'dt-for-linus' of git://git.secretlab.ca/git/linux: of/irq: do irq resolution in platform_get_irq of: selftest: add deferred probe interrupt test dt: Fix binding typos in clock-names and interrupt-names
Showing 14 changed files Inline Diff
- Documentation/devicetree/bindings/net/socfpga-dwmac.txt
- Documentation/devicetree/bindings/net/stmmac.txt
- Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
- Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
- arch/arm/boot/dts/am33xx.dtsi
- arch/arm/boot/dts/am4372.dtsi
- arch/arm/boot/dts/stih415-pinctrl.dtsi
- arch/arm/boot/dts/stih416-pinctrl.dtsi
- drivers/base/platform.c
- drivers/of/irq.c
- drivers/of/platform.c
- drivers/of/selftest.c
- drivers/of/testcase-data/tests-interrupts.dtsi
- include/linux/of_irq.h
Documentation/devicetree/bindings/net/socfpga-dwmac.txt
1 | Altera SOCFPGA SoC DWMAC controller | 1 | Altera SOCFPGA SoC DWMAC controller |
2 | 2 | ||
3 | This is a variant of the dwmac/stmmac driver an inherits all descriptions | 3 | This is a variant of the dwmac/stmmac driver an inherits all descriptions |
4 | present in Documentation/devicetree/bindings/net/stmmac.txt. | 4 | present in Documentation/devicetree/bindings/net/stmmac.txt. |
5 | 5 | ||
6 | The device node has additional properties: | 6 | The device node has additional properties: |
7 | 7 | ||
8 | Required properties: | 8 | Required properties: |
9 | - compatible : Should contain "altr,socfpga-stmmac" along with | 9 | - compatible : Should contain "altr,socfpga-stmmac" along with |
10 | "snps,dwmac" and any applicable more detailed | 10 | "snps,dwmac" and any applicable more detailed |
11 | designware version numbers documented in stmmac.txt | 11 | designware version numbers documented in stmmac.txt |
12 | - altr,sysmgr-syscon : Should be the phandle to the system manager node that | 12 | - altr,sysmgr-syscon : Should be the phandle to the system manager node that |
13 | encompasses the glue register, the register offset, and the register shift. | 13 | encompasses the glue register, the register offset, and the register shift. |
14 | 14 | ||
15 | Example: | 15 | Example: |
16 | 16 | ||
17 | gmac0: ethernet@ff700000 { | 17 | gmac0: ethernet@ff700000 { |
18 | compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; | 18 | compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; |
19 | altr,sysmgr-syscon = <&sysmgr 0x60 0>; | 19 | altr,sysmgr-syscon = <&sysmgr 0x60 0>; |
20 | status = "disabled"; | 20 | status = "disabled"; |
21 | reg = <0xff700000 0x2000>; | 21 | reg = <0xff700000 0x2000>; |
22 | interrupts = <0 115 4>; | 22 | interrupts = <0 115 4>; |
23 | interrupt-names = "macirq"; | 23 | interrupt-names = "macirq"; |
24 | mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ | 24 | mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ |
25 | clocks = <&emac_0_clk>; | 25 | clocks = <&emac_0_clk>; |
26 | clocks-names = "stmmaceth"; | 26 | clock-names = "stmmaceth"; |
27 | }; | 27 | }; |
28 | 28 |
Documentation/devicetree/bindings/net/stmmac.txt
1 | * STMicroelectronics 10/100/1000 Ethernet driver (GMAC) | 1 | * STMicroelectronics 10/100/1000 Ethernet driver (GMAC) |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: Should be "snps,dwmac-<ip_version>" "snps,dwmac" | 4 | - compatible: Should be "snps,dwmac-<ip_version>" "snps,dwmac" |
5 | For backwards compatibility: "st,spear600-gmac" is also supported. | 5 | For backwards compatibility: "st,spear600-gmac" is also supported. |
6 | - reg: Address and length of the register set for the device | 6 | - reg: Address and length of the register set for the device |
7 | - interrupt-parent: Should be the phandle for the interrupt controller | 7 | - interrupt-parent: Should be the phandle for the interrupt controller |
8 | that services interrupts for this device | 8 | that services interrupts for this device |
9 | - interrupts: Should contain the STMMAC interrupts | 9 | - interrupts: Should contain the STMMAC interrupts |
10 | - interrupt-names: Should contain the interrupt names "macirq" | 10 | - interrupt-names: Should contain the interrupt names "macirq" |
11 | "eth_wake_irq" if this interrupt is supported in the "interrupts" | 11 | "eth_wake_irq" if this interrupt is supported in the "interrupts" |
12 | property | 12 | property |
13 | - phy-mode: See ethernet.txt file in the same directory. | 13 | - phy-mode: See ethernet.txt file in the same directory. |
14 | - snps,reset-gpio gpio number for phy reset. | 14 | - snps,reset-gpio gpio number for phy reset. |
15 | - snps,reset-active-low boolean flag to indicate if phy reset is active low. | 15 | - snps,reset-active-low boolean flag to indicate if phy reset is active low. |
16 | - snps,reset-delays-us is triplet of delays | 16 | - snps,reset-delays-us is triplet of delays |
17 | The 1st cell is reset pre-delay in micro seconds. | 17 | The 1st cell is reset pre-delay in micro seconds. |
18 | The 2nd cell is reset pulse in micro seconds. | 18 | The 2nd cell is reset pulse in micro seconds. |
19 | The 3rd cell is reset post-delay in micro seconds. | 19 | The 3rd cell is reset post-delay in micro seconds. |
20 | - snps,pbl Programmable Burst Length | 20 | - snps,pbl Programmable Burst Length |
21 | - snps,fixed-burst Program the DMA to use the fixed burst mode | 21 | - snps,fixed-burst Program the DMA to use the fixed burst mode |
22 | - snps,mixed-burst Program the DMA to use the mixed burst mode | 22 | - snps,mixed-burst Program the DMA to use the mixed burst mode |
23 | - snps,force_thresh_dma_mode Force DMA to use the threshold mode for | 23 | - snps,force_thresh_dma_mode Force DMA to use the threshold mode for |
24 | both tx and rx | 24 | both tx and rx |
25 | - snps,force_sf_dma_mode Force DMA to use the Store and Forward | 25 | - snps,force_sf_dma_mode Force DMA to use the Store and Forward |
26 | mode for both tx and rx. This flag is | 26 | mode for both tx and rx. This flag is |
27 | ignored if force_thresh_dma_mode is set. | 27 | ignored if force_thresh_dma_mode is set. |
28 | 28 | ||
29 | Optional properties: | 29 | Optional properties: |
30 | - resets: Should contain a phandle to the STMMAC reset signal, if any | 30 | - resets: Should contain a phandle to the STMMAC reset signal, if any |
31 | - reset-names: Should contain the reset signal name "stmmaceth", if a | 31 | - reset-names: Should contain the reset signal name "stmmaceth", if a |
32 | reset phandle is given | 32 | reset phandle is given |
33 | - max-frame-size: See ethernet.txt file in the same directory | 33 | - max-frame-size: See ethernet.txt file in the same directory |
34 | - clocks: If present, the first clock should be the GMAC main clock, | 34 | - clocks: If present, the first clock should be the GMAC main clock, |
35 | further clocks may be specified in derived bindings. | 35 | further clocks may be specified in derived bindings. |
36 | - clocks-names: One name for each entry in the clocks property, the | 36 | - clock-names: One name for each entry in the clocks property, the |
37 | first one should be "stmmaceth". | 37 | first one should be "stmmaceth". |
38 | 38 | ||
39 | Examples: | 39 | Examples: |
40 | 40 | ||
41 | gmac0: ethernet@e0800000 { | 41 | gmac0: ethernet@e0800000 { |
42 | compatible = "st,spear600-gmac"; | 42 | compatible = "st,spear600-gmac"; |
43 | reg = <0xe0800000 0x8000>; | 43 | reg = <0xe0800000 0x8000>; |
44 | interrupt-parent = <&vic1>; | 44 | interrupt-parent = <&vic1>; |
45 | interrupts = <24 23>; | 45 | interrupts = <24 23>; |
46 | interrupt-names = "macirq", "eth_wake_irq"; | 46 | interrupt-names = "macirq", "eth_wake_irq"; |
47 | mac-address = [000000000000]; /* Filled in by U-Boot */ | 47 | mac-address = [000000000000]; /* Filled in by U-Boot */ |
48 | max-frame-size = <3800>; | 48 | max-frame-size = <3800>; |
49 | phy-mode = "gmii"; | 49 | phy-mode = "gmii"; |
50 | clocks = <&clock>; | 50 | clocks = <&clock>; |
51 | clock-names = "stmmaceth">; | 51 | clock-names = "stmmaceth">; |
52 | }; | 52 | }; |
53 | 53 |
Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
1 | *ST pin controller. | 1 | *ST pin controller. |
2 | 2 | ||
3 | Each multi-function pin is controlled, driven and routed through the | 3 | Each multi-function pin is controlled, driven and routed through the |
4 | PIO multiplexing block. Each pin supports GPIO functionality (ALT0) | 4 | PIO multiplexing block. Each pin supports GPIO functionality (ALT0) |
5 | and multiple alternate functions(ALT1 - ALTx) that directly connect | 5 | and multiple alternate functions(ALT1 - ALTx) that directly connect |
6 | the pin to different hardware blocks. | 6 | the pin to different hardware blocks. |
7 | 7 | ||
8 | When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and | 8 | When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and |
9 | Pull Up (PU) are driven by the related PIO block. | 9 | Pull Up (PU) are driven by the related PIO block. |
10 | 10 | ||
11 | ST pinctrl driver controls PIO multiplexing block and also interacts with | 11 | ST pinctrl driver controls PIO multiplexing block and also interacts with |
12 | gpio driver to configure a pin. | 12 | gpio driver to configure a pin. |
13 | 13 | ||
14 | GPIO bank can have one of the two possible types of interrupt-wirings. | 14 | GPIO bank can have one of the two possible types of interrupt-wirings. |
15 | 15 | ||
16 | First type is via irqmux, single interrupt is used by multiple gpio banks. This | 16 | First type is via irqmux, single interrupt is used by multiple gpio banks. This |
17 | reduces number of overall interrupts numbers required. All these banks belong to | 17 | reduces number of overall interrupts numbers required. All these banks belong to |
18 | a single pincontroller. | 18 | a single pincontroller. |
19 | _________ | 19 | _________ |
20 | | |----> [gpio-bank (n) ] | 20 | | |----> [gpio-bank (n) ] |
21 | | |----> [gpio-bank (n + 1)] | 21 | | |----> [gpio-bank (n + 1)] |
22 | [irqN]-- | irq-mux |----> [gpio-bank (n + 2)] | 22 | [irqN]-- | irq-mux |----> [gpio-bank (n + 2)] |
23 | | |----> [gpio-bank (... )] | 23 | | |----> [gpio-bank (... )] |
24 | |_________|----> [gpio-bank (n + 7)] | 24 | |_________|----> [gpio-bank (n + 7)] |
25 | 25 | ||
26 | Second type has a dedicated interrupt per gpio bank. | 26 | Second type has a dedicated interrupt per gpio bank. |
27 | 27 | ||
28 | [irqN]----> [gpio-bank (n)] | 28 | [irqN]----> [gpio-bank (n)] |
29 | 29 | ||
30 | 30 | ||
31 | Pin controller node: | 31 | Pin controller node: |
32 | Required properties: | 32 | Required properties: |
33 | - compatible : should be "st,<SOC>-<pio-block>-pinctrl" | 33 | - compatible : should be "st,<SOC>-<pio-block>-pinctrl" |
34 | like st,stih415-sbc-pinctrl, st,stih415-front-pinctrl and so on. | 34 | like st,stih415-sbc-pinctrl, st,stih415-front-pinctrl and so on. |
35 | - st,syscfg : Should be a phandle of the syscfg node. | 35 | - st,syscfg : Should be a phandle of the syscfg node. |
36 | - st,retime-pin-mask : Should be mask to specify which pins can be retimed. | 36 | - st,retime-pin-mask : Should be mask to specify which pins can be retimed. |
37 | If the property is not present, it is assumed that all the pins in the | 37 | If the property is not present, it is assumed that all the pins in the |
38 | bank are capable of retiming. Retiming is mainly used to improve the | 38 | bank are capable of retiming. Retiming is mainly used to improve the |
39 | IO timing margins of external synchronous interfaces. | 39 | IO timing margins of external synchronous interfaces. |
40 | - ranges : defines mapping between pin controller node (parent) to gpio-bank | 40 | - ranges : defines mapping between pin controller node (parent) to gpio-bank |
41 | node (children). | 41 | node (children). |
42 | 42 | ||
43 | Optional properties: | 43 | Optional properties: |
44 | - interrupts : Interrupt number of the irqmux. If the interrupt is shared | 44 | - interrupts : Interrupt number of the irqmux. If the interrupt is shared |
45 | with other gpio banks via irqmux. | 45 | with other gpio banks via irqmux. |
46 | a irqline and gpio banks. | 46 | a irqline and gpio banks. |
47 | - reg : irqmux memory resource. If irqmux is present. | 47 | - reg : irqmux memory resource. If irqmux is present. |
48 | - reg-names : irqmux resource should be named as "irqmux". | 48 | - reg-names : irqmux resource should be named as "irqmux". |
49 | 49 | ||
50 | GPIO controller/bank node. | 50 | GPIO controller/bank node. |
51 | Required properties: | 51 | Required properties: |
52 | - gpio-controller : Indicates this device is a GPIO controller | 52 | - gpio-controller : Indicates this device is a GPIO controller |
53 | - #gpio-cells : Should be one. The first cell is the pin number. | 53 | - #gpio-cells : Should be one. The first cell is the pin number. |
54 | - st,bank-name : Should be a name string for this bank as specified in | 54 | - st,bank-name : Should be a name string for this bank as specified in |
55 | datasheet. | 55 | datasheet. |
56 | 56 | ||
57 | Optional properties: | 57 | Optional properties: |
58 | - interrupts : Interrupt number for this gpio bank. If there is a dedicated | 58 | - interrupts : Interrupt number for this gpio bank. If there is a dedicated |
59 | interrupt wired up for this gpio bank. | 59 | interrupt wired up for this gpio bank. |
60 | 60 | ||
61 | - interrupt-controller : Indicates this device is a interrupt controller. GPIO | 61 | - interrupt-controller : Indicates this device is a interrupt controller. GPIO |
62 | bank can be an interrupt controller iff one of the interrupt type either via | 62 | bank can be an interrupt controller iff one of the interrupt type either via |
63 | irqmux or a dedicated interrupt per bank is specified. | 63 | irqmux or a dedicated interrupt per bank is specified. |
64 | 64 | ||
65 | - #interrupt-cells: the value of this property should be 2. | 65 | - #interrupt-cells: the value of this property should be 2. |
66 | - First Cell: represents the external gpio interrupt number local to the | 66 | - First Cell: represents the external gpio interrupt number local to the |
67 | gpio interrupt space of the controller. | 67 | gpio interrupt space of the controller. |
68 | - Second Cell: flags to identify the type of the interrupt | 68 | - Second Cell: flags to identify the type of the interrupt |
69 | - 1 = rising edge triggered | 69 | - 1 = rising edge triggered |
70 | - 2 = falling edge triggered | 70 | - 2 = falling edge triggered |
71 | - 3 = rising and falling edge triggered | 71 | - 3 = rising and falling edge triggered |
72 | - 4 = high level triggered | 72 | - 4 = high level triggered |
73 | - 8 = low level triggered | 73 | - 8 = low level triggered |
74 | for related macros look in: | 74 | for related macros look in: |
75 | include/dt-bindings/interrupt-controller/irq.h | 75 | include/dt-bindings/interrupt-controller/irq.h |
76 | 76 | ||
77 | Example: | 77 | Example: |
78 | pin-controller-sbc { | 78 | pin-controller-sbc { |
79 | #address-cells = <1>; | 79 | #address-cells = <1>; |
80 | #size-cells = <1>; | 80 | #size-cells = <1>; |
81 | compatible = "st,stih415-sbc-pinctrl"; | 81 | compatible = "st,stih415-sbc-pinctrl"; |
82 | st,syscfg = <&syscfg_sbc>; | 82 | st,syscfg = <&syscfg_sbc>; |
83 | reg = <0xfe61f080 0x4>; | 83 | reg = <0xfe61f080 0x4>; |
84 | reg-names = "irqmux"; | 84 | reg-names = "irqmux"; |
85 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; | 85 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; |
86 | interrupts-names = "irqmux"; | 86 | interrupt-names = "irqmux"; |
87 | ranges = <0 0xfe610000 0x5000>; | 87 | ranges = <0 0xfe610000 0x5000>; |
88 | 88 | ||
89 | PIO0: gpio@fe610000 { | 89 | PIO0: gpio@fe610000 { |
90 | gpio-controller; | 90 | gpio-controller; |
91 | #gpio-cells = <1>; | 91 | #gpio-cells = <1>; |
92 | interrupt-controller; | 92 | interrupt-controller; |
93 | #interrupt-cells = <2>; | 93 | #interrupt-cells = <2>; |
94 | reg = <0 0x100>; | 94 | reg = <0 0x100>; |
95 | st,bank-name = "PIO0"; | 95 | st,bank-name = "PIO0"; |
96 | }; | 96 | }; |
97 | ... | 97 | ... |
98 | pin-functions nodes follow... | 98 | pin-functions nodes follow... |
99 | }; | 99 | }; |
100 | 100 | ||
101 | 101 | ||
102 | Contents of function subnode node: | 102 | Contents of function subnode node: |
103 | ---------------------- | 103 | ---------------------- |
104 | Required properties for pin configuration node: | 104 | Required properties for pin configuration node: |
105 | - st,pins : Child node with list of pins with configuration. | 105 | - st,pins : Child node with list of pins with configuration. |
106 | 106 | ||
107 | Below is the format of how each pin conf should look like. | 107 | Below is the format of how each pin conf should look like. |
108 | 108 | ||
109 | <bank offset mux mode rt_type rt_delay rt_clk> | 109 | <bank offset mux mode rt_type rt_delay rt_clk> |
110 | 110 | ||
111 | Every PIO is represented with 4-7 parameters depending on retime configuration. | 111 | Every PIO is represented with 4-7 parameters depending on retime configuration. |
112 | Each parameter is explained as below. | 112 | Each parameter is explained as below. |
113 | 113 | ||
114 | -bank : Should be bank phandle to which this PIO belongs. | 114 | -bank : Should be bank phandle to which this PIO belongs. |
115 | -offset : Offset in the PIO bank. | 115 | -offset : Offset in the PIO bank. |
116 | -mux : Should be alternate function number associated this pin. | 116 | -mux : Should be alternate function number associated this pin. |
117 | Use same numbers from datasheet. | 117 | Use same numbers from datasheet. |
118 | -mode :pin configuration is selected from one of the below values. | 118 | -mode :pin configuration is selected from one of the below values. |
119 | IN | 119 | IN |
120 | IN_PU | 120 | IN_PU |
121 | OUT | 121 | OUT |
122 | BIDIR | 122 | BIDIR |
123 | BIDIR_PU | 123 | BIDIR_PU |
124 | 124 | ||
125 | -rt_type Retiming Configuration for the pin. | 125 | -rt_type Retiming Configuration for the pin. |
126 | Possible retime configuration are: | 126 | Possible retime configuration are: |
127 | 127 | ||
128 | ------- ------------- | 128 | ------- ------------- |
129 | value args | 129 | value args |
130 | ------- ------------- | 130 | ------- ------------- |
131 | NICLK <delay> <clk> | 131 | NICLK <delay> <clk> |
132 | ICLK_IO <delay> <clk> | 132 | ICLK_IO <delay> <clk> |
133 | BYPASS <delay> | 133 | BYPASS <delay> |
134 | DE_IO <delay> <clk> | 134 | DE_IO <delay> <clk> |
135 | SE_ICLK_IO <delay> <clk> | 135 | SE_ICLK_IO <delay> <clk> |
136 | SE_NICLK_IO <delay> <clk> | 136 | SE_NICLK_IO <delay> <clk> |
137 | 137 | ||
138 | - delay is retime delay in pico seconds as mentioned in data sheet. | 138 | - delay is retime delay in pico seconds as mentioned in data sheet. |
139 | 139 | ||
140 | - rt_clk :clk to be use for retime. | 140 | - rt_clk :clk to be use for retime. |
141 | Possible values are: | 141 | Possible values are: |
142 | CLK_A | 142 | CLK_A |
143 | CLK_B | 143 | CLK_B |
144 | CLK_C | 144 | CLK_C |
145 | CLK_D | 145 | CLK_D |
146 | 146 | ||
147 | Example of mmcclk pin which is a bi-direction pull pu with retime config | 147 | Example of mmcclk pin which is a bi-direction pull pu with retime config |
148 | as non inverted clock retimed with CLK_B and delay of 0 pico seconds: | 148 | as non inverted clock retimed with CLK_B and delay of 0 pico seconds: |
149 | 149 | ||
150 | pin-controller { | 150 | pin-controller { |
151 | ... | 151 | ... |
152 | mmc0 { | 152 | mmc0 { |
153 | pinctrl_mmc: mmc { | 153 | pinctrl_mmc: mmc { |
154 | st,pins { | 154 | st,pins { |
155 | mmcclk = <&PIO13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>; | 155 | mmcclk = <&PIO13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>; |
156 | ... | 156 | ... |
157 | }; | 157 | }; |
158 | }; | 158 | }; |
159 | ... | 159 | ... |
160 | }; | 160 | }; |
161 | }; | 161 | }; |
162 | 162 | ||
163 | sdhci0:sdhci@fe810000{ | 163 | sdhci0:sdhci@fe810000{ |
164 | ... | 164 | ... |
165 | interrupt-parent = <&PIO3>; | 165 | interrupt-parent = <&PIO3>; |
166 | #interrupt-cells = <2>; | 166 | #interrupt-cells = <2>; |
167 | interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; /* Interrupt line via PIO3-3 */ | 167 | interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; /* Interrupt line via PIO3-3 */ |
168 | interrupts-names = "card-detect"; | 168 | interrupt-names = "card-detect"; |
169 | pinctrl-names = "default"; | 169 | pinctrl-names = "default"; |
170 | pinctrl-0 = <&pinctrl_mmc>; | 170 | pinctrl-0 = <&pinctrl_mmc>; |
171 | }; | 171 | }; |
172 | 172 |
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
1 | Texas Instruments McASP controller | 1 | Texas Instruments McASP controller |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : | 4 | - compatible : |
5 | "ti,dm646x-mcasp-audio" : for DM646x platforms | 5 | "ti,dm646x-mcasp-audio" : for DM646x platforms |
6 | "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms | 6 | "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms |
7 | "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) | 7 | "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) |
8 | "ti,dra7-mcasp-audio" : for DRA7xx platforms | 8 | "ti,dra7-mcasp-audio" : for DRA7xx platforms |
9 | 9 | ||
10 | - reg : Should contain reg specifiers for the entries in the reg-names property. | 10 | - reg : Should contain reg specifiers for the entries in the reg-names property. |
11 | - reg-names : Should contain: | 11 | - reg-names : Should contain: |
12 | * "mpu" for the main registers (required). For compatibility with | 12 | * "mpu" for the main registers (required). For compatibility with |
13 | existing software, it is recommended this is the first entry. | 13 | existing software, it is recommended this is the first entry. |
14 | * "dat" for separate data port register access (optional). | 14 | * "dat" for separate data port register access (optional). |
15 | - op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF, | 15 | - op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF, |
16 | IEC60958-1, and AES-3 formats. | 16 | IEC60958-1, and AES-3 formats. |
17 | - tdm-slots : Slots for TDM operation. Indicates number of channels transmitted | 17 | - tdm-slots : Slots for TDM operation. Indicates number of channels transmitted |
18 | or received over one serializer. | 18 | or received over one serializer. |
19 | - serial-dir : A list of serializer configuration. Each entry is a number | 19 | - serial-dir : A list of serializer configuration. Each entry is a number |
20 | indication for serializer pin direction. | 20 | indication for serializer pin direction. |
21 | (0 - INACTIVE, 1 - TX, 2 - RX) | 21 | (0 - INACTIVE, 1 - TX, 2 - RX) |
22 | - dmas: two element list of DMA controller phandles and DMA request line | 22 | - dmas: two element list of DMA controller phandles and DMA request line |
23 | ordered pairs. | 23 | ordered pairs. |
24 | - dma-names: identifier string for each DMA request line in the dmas property. | 24 | - dma-names: identifier string for each DMA request line in the dmas property. |
25 | These strings correspond 1:1 with the ordered pairs in dmas. The dma | 25 | These strings correspond 1:1 with the ordered pairs in dmas. The dma |
26 | identifiers must be "rx" and "tx". | 26 | identifiers must be "rx" and "tx". |
27 | 27 | ||
28 | Optional properties: | 28 | Optional properties: |
29 | 29 | ||
30 | - ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0 | 30 | - ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0 |
31 | - tx-num-evt : FIFO levels. | 31 | - tx-num-evt : FIFO levels. |
32 | - rx-num-evt : FIFO levels. | 32 | - rx-num-evt : FIFO levels. |
33 | - sram-size-playback : size of sram to be allocated during playback | 33 | - sram-size-playback : size of sram to be allocated during playback |
34 | - sram-size-capture : size of sram to be allocated during capture | 34 | - sram-size-capture : size of sram to be allocated during capture |
35 | - interrupts : Interrupt numbers for McASP, currently not used by the driver | 35 | - interrupts : Interrupt numbers for McASP, currently not used by the driver |
36 | - interrupt-names : Known interrupt names are "tx" and "rx" | 36 | - interrupt-names : Known interrupt names are "tx" and "rx" |
37 | - pinctrl-0: Should specify pin control group used for this controller. | 37 | - pinctrl-0: Should specify pin control group used for this controller. |
38 | - pinctrl-names: Should contain only one value - "default", for more details | 38 | - pinctrl-names: Should contain only one value - "default", for more details |
39 | please refer to pinctrl-bindings.txt | 39 | please refer to pinctrl-bindings.txt |
40 | - fck_parent : Should contain a valid clock name which will be used as parent | 40 | - fck_parent : Should contain a valid clock name which will be used as parent |
41 | for the McASP fck | 41 | for the McASP fck |
42 | 42 | ||
43 | Example: | 43 | Example: |
44 | 44 | ||
45 | mcasp0: mcasp0@1d00000 { | 45 | mcasp0: mcasp0@1d00000 { |
46 | compatible = "ti,da830-mcasp-audio"; | 46 | compatible = "ti,da830-mcasp-audio"; |
47 | reg = <0x100000 0x3000>; | 47 | reg = <0x100000 0x3000>; |
48 | reg-names "mpu"; | 48 | reg-names "mpu"; |
49 | interrupts = <82>, <83>; | 49 | interrupts = <82>, <83>; |
50 | interrupts-names = "tx", "rx"; | 50 | interrupt-names = "tx", "rx"; |
51 | op-mode = <0>; /* MCASP_IIS_MODE */ | 51 | op-mode = <0>; /* MCASP_IIS_MODE */ |
52 | tdm-slots = <2>; | 52 | tdm-slots = <2>; |
53 | serial-dir = < | 53 | serial-dir = < |
54 | 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */ | 54 | 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */ |
55 | 0 0 0 0 | 55 | 0 0 0 0 |
56 | 0 0 0 1 | 56 | 0 0 0 1 |
57 | 2 0 0 0 >; | 57 | 2 0 0 0 >; |
58 | tx-num-evt = <1>; | 58 | tx-num-evt = <1>; |
59 | rx-num-evt = <1>; | 59 | rx-num-evt = <1>; |
60 | }; | 60 | }; |
61 | 61 |
arch/arm/boot/dts/am33xx.dtsi
1 | /* | 1 | /* |
2 | * Device Tree Source for AM33XX SoC | 2 | * Device Tree Source for AM33XX SoC |
3 | * | 3 | * |
4 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * | 5 | * |
6 | * This file is licensed under the terms of the GNU General Public License | 6 | * This file is licensed under the terms of the GNU General Public License |
7 | * version 2. This program is licensed "as is" without any warranty of any | 7 | * version 2. This program is licensed "as is" without any warranty of any |
8 | * kind, whether express or implied. | 8 | * kind, whether express or implied. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <dt-bindings/gpio/gpio.h> | 11 | #include <dt-bindings/gpio/gpio.h> |
12 | #include <dt-bindings/pinctrl/am33xx.h> | 12 | #include <dt-bindings/pinctrl/am33xx.h> |
13 | 13 | ||
14 | #include "skeleton.dtsi" | 14 | #include "skeleton.dtsi" |
15 | 15 | ||
16 | / { | 16 | / { |
17 | compatible = "ti,am33xx"; | 17 | compatible = "ti,am33xx"; |
18 | interrupt-parent = <&intc>; | 18 | interrupt-parent = <&intc>; |
19 | 19 | ||
20 | aliases { | 20 | aliases { |
21 | i2c0 = &i2c0; | 21 | i2c0 = &i2c0; |
22 | i2c1 = &i2c1; | 22 | i2c1 = &i2c1; |
23 | i2c2 = &i2c2; | 23 | i2c2 = &i2c2; |
24 | serial0 = &uart0; | 24 | serial0 = &uart0; |
25 | serial1 = &uart1; | 25 | serial1 = &uart1; |
26 | serial2 = &uart2; | 26 | serial2 = &uart2; |
27 | serial3 = &uart3; | 27 | serial3 = &uart3; |
28 | serial4 = &uart4; | 28 | serial4 = &uart4; |
29 | serial5 = &uart5; | 29 | serial5 = &uart5; |
30 | d_can0 = &dcan0; | 30 | d_can0 = &dcan0; |
31 | d_can1 = &dcan1; | 31 | d_can1 = &dcan1; |
32 | usb0 = &usb0; | 32 | usb0 = &usb0; |
33 | usb1 = &usb1; | 33 | usb1 = &usb1; |
34 | phy0 = &usb0_phy; | 34 | phy0 = &usb0_phy; |
35 | phy1 = &usb1_phy; | 35 | phy1 = &usb1_phy; |
36 | ethernet0 = &cpsw_emac0; | 36 | ethernet0 = &cpsw_emac0; |
37 | ethernet1 = &cpsw_emac1; | 37 | ethernet1 = &cpsw_emac1; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | cpus { | 40 | cpus { |
41 | #address-cells = <1>; | 41 | #address-cells = <1>; |
42 | #size-cells = <0>; | 42 | #size-cells = <0>; |
43 | cpu@0 { | 43 | cpu@0 { |
44 | compatible = "arm,cortex-a8"; | 44 | compatible = "arm,cortex-a8"; |
45 | device_type = "cpu"; | 45 | device_type = "cpu"; |
46 | reg = <0>; | 46 | reg = <0>; |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * To consider voltage drop between PMIC and SoC, | 49 | * To consider voltage drop between PMIC and SoC, |
50 | * tolerance value is reduced to 2% from 4% and | 50 | * tolerance value is reduced to 2% from 4% and |
51 | * voltage value is increased as a precaution. | 51 | * voltage value is increased as a precaution. |
52 | */ | 52 | */ |
53 | operating-points = < | 53 | operating-points = < |
54 | /* kHz uV */ | 54 | /* kHz uV */ |
55 | 720000 1285000 | 55 | 720000 1285000 |
56 | 600000 1225000 | 56 | 600000 1225000 |
57 | 500000 1125000 | 57 | 500000 1125000 |
58 | 275000 1125000 | 58 | 275000 1125000 |
59 | >; | 59 | >; |
60 | voltage-tolerance = <2>; /* 2 percentage */ | 60 | voltage-tolerance = <2>; /* 2 percentage */ |
61 | 61 | ||
62 | clocks = <&dpll_mpu_ck>; | 62 | clocks = <&dpll_mpu_ck>; |
63 | clock-names = "cpu"; | 63 | clock-names = "cpu"; |
64 | 64 | ||
65 | clock-latency = <300000>; /* From omap-cpufreq driver */ | 65 | clock-latency = <300000>; /* From omap-cpufreq driver */ |
66 | }; | 66 | }; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | pmu { | 69 | pmu { |
70 | compatible = "arm,cortex-a8-pmu"; | 70 | compatible = "arm,cortex-a8-pmu"; |
71 | interrupts = <3>; | 71 | interrupts = <3>; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * The soc node represents the soc top level view. It is used for IPs | 75 | * The soc node represents the soc top level view. It is used for IPs |
76 | * that are not memory mapped in the MPU view or for the MPU itself. | 76 | * that are not memory mapped in the MPU view or for the MPU itself. |
77 | */ | 77 | */ |
78 | soc { | 78 | soc { |
79 | compatible = "ti,omap-infra"; | 79 | compatible = "ti,omap-infra"; |
80 | mpu { | 80 | mpu { |
81 | compatible = "ti,omap3-mpu"; | 81 | compatible = "ti,omap3-mpu"; |
82 | ti,hwmods = "mpu"; | 82 | ti,hwmods = "mpu"; |
83 | }; | 83 | }; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | am33xx_pinmux: pinmux@44e10800 { | 86 | am33xx_pinmux: pinmux@44e10800 { |
87 | compatible = "pinctrl-single"; | 87 | compatible = "pinctrl-single"; |
88 | reg = <0x44e10800 0x0238>; | 88 | reg = <0x44e10800 0x0238>; |
89 | #address-cells = <1>; | 89 | #address-cells = <1>; |
90 | #size-cells = <0>; | 90 | #size-cells = <0>; |
91 | pinctrl-single,register-width = <32>; | 91 | pinctrl-single,register-width = <32>; |
92 | pinctrl-single,function-mask = <0x7f>; | 92 | pinctrl-single,function-mask = <0x7f>; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * XXX: Use a flat representation of the AM33XX interconnect. | 96 | * XXX: Use a flat representation of the AM33XX interconnect. |
97 | * The real AM33XX interconnect network is quite complex. Since | 97 | * The real AM33XX interconnect network is quite complex. Since |
98 | * it will not bring real advantage to represent that in DT | 98 | * it will not bring real advantage to represent that in DT |
99 | * for the moment, just use a fake OCP bus entry to represent | 99 | * for the moment, just use a fake OCP bus entry to represent |
100 | * the whole bus hierarchy. | 100 | * the whole bus hierarchy. |
101 | */ | 101 | */ |
102 | ocp { | 102 | ocp { |
103 | compatible = "simple-bus"; | 103 | compatible = "simple-bus"; |
104 | #address-cells = <1>; | 104 | #address-cells = <1>; |
105 | #size-cells = <1>; | 105 | #size-cells = <1>; |
106 | ranges; | 106 | ranges; |
107 | ti,hwmods = "l3_main"; | 107 | ti,hwmods = "l3_main"; |
108 | 108 | ||
109 | prcm: prcm@44e00000 { | 109 | prcm: prcm@44e00000 { |
110 | compatible = "ti,am3-prcm"; | 110 | compatible = "ti,am3-prcm"; |
111 | reg = <0x44e00000 0x4000>; | 111 | reg = <0x44e00000 0x4000>; |
112 | 112 | ||
113 | prcm_clocks: clocks { | 113 | prcm_clocks: clocks { |
114 | #address-cells = <1>; | 114 | #address-cells = <1>; |
115 | #size-cells = <0>; | 115 | #size-cells = <0>; |
116 | }; | 116 | }; |
117 | 117 | ||
118 | prcm_clockdomains: clockdomains { | 118 | prcm_clockdomains: clockdomains { |
119 | }; | 119 | }; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | scrm: scrm@44e10000 { | 122 | scrm: scrm@44e10000 { |
123 | compatible = "ti,am3-scrm"; | 123 | compatible = "ti,am3-scrm"; |
124 | reg = <0x44e10000 0x2000>; | 124 | reg = <0x44e10000 0x2000>; |
125 | 125 | ||
126 | scrm_clocks: clocks { | 126 | scrm_clocks: clocks { |
127 | #address-cells = <1>; | 127 | #address-cells = <1>; |
128 | #size-cells = <0>; | 128 | #size-cells = <0>; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | scrm_clockdomains: clockdomains { | 131 | scrm_clockdomains: clockdomains { |
132 | }; | 132 | }; |
133 | }; | 133 | }; |
134 | 134 | ||
135 | intc: interrupt-controller@48200000 { | 135 | intc: interrupt-controller@48200000 { |
136 | compatible = "ti,omap2-intc"; | 136 | compatible = "ti,omap2-intc"; |
137 | interrupt-controller; | 137 | interrupt-controller; |
138 | #interrupt-cells = <1>; | 138 | #interrupt-cells = <1>; |
139 | ti,intc-size = <128>; | 139 | ti,intc-size = <128>; |
140 | reg = <0x48200000 0x1000>; | 140 | reg = <0x48200000 0x1000>; |
141 | }; | 141 | }; |
142 | 142 | ||
143 | edma: edma@49000000 { | 143 | edma: edma@49000000 { |
144 | compatible = "ti,edma3"; | 144 | compatible = "ti,edma3"; |
145 | ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; | 145 | ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; |
146 | reg = <0x49000000 0x10000>, | 146 | reg = <0x49000000 0x10000>, |
147 | <0x44e10f90 0x10>; | 147 | <0x44e10f90 0x10>; |
148 | interrupts = <12 13 14>; | 148 | interrupts = <12 13 14>; |
149 | #dma-cells = <1>; | 149 | #dma-cells = <1>; |
150 | dma-channels = <64>; | 150 | dma-channels = <64>; |
151 | ti,edma-regions = <4>; | 151 | ti,edma-regions = <4>; |
152 | ti,edma-slots = <256>; | 152 | ti,edma-slots = <256>; |
153 | }; | 153 | }; |
154 | 154 | ||
155 | gpio0: gpio@44e07000 { | 155 | gpio0: gpio@44e07000 { |
156 | compatible = "ti,omap4-gpio"; | 156 | compatible = "ti,omap4-gpio"; |
157 | ti,hwmods = "gpio1"; | 157 | ti,hwmods = "gpio1"; |
158 | gpio-controller; | 158 | gpio-controller; |
159 | #gpio-cells = <2>; | 159 | #gpio-cells = <2>; |
160 | interrupt-controller; | 160 | interrupt-controller; |
161 | #interrupt-cells = <2>; | 161 | #interrupt-cells = <2>; |
162 | reg = <0x44e07000 0x1000>; | 162 | reg = <0x44e07000 0x1000>; |
163 | interrupts = <96>; | 163 | interrupts = <96>; |
164 | }; | 164 | }; |
165 | 165 | ||
166 | gpio1: gpio@4804c000 { | 166 | gpio1: gpio@4804c000 { |
167 | compatible = "ti,omap4-gpio"; | 167 | compatible = "ti,omap4-gpio"; |
168 | ti,hwmods = "gpio2"; | 168 | ti,hwmods = "gpio2"; |
169 | gpio-controller; | 169 | gpio-controller; |
170 | #gpio-cells = <2>; | 170 | #gpio-cells = <2>; |
171 | interrupt-controller; | 171 | interrupt-controller; |
172 | #interrupt-cells = <2>; | 172 | #interrupt-cells = <2>; |
173 | reg = <0x4804c000 0x1000>; | 173 | reg = <0x4804c000 0x1000>; |
174 | interrupts = <98>; | 174 | interrupts = <98>; |
175 | }; | 175 | }; |
176 | 176 | ||
177 | gpio2: gpio@481ac000 { | 177 | gpio2: gpio@481ac000 { |
178 | compatible = "ti,omap4-gpio"; | 178 | compatible = "ti,omap4-gpio"; |
179 | ti,hwmods = "gpio3"; | 179 | ti,hwmods = "gpio3"; |
180 | gpio-controller; | 180 | gpio-controller; |
181 | #gpio-cells = <2>; | 181 | #gpio-cells = <2>; |
182 | interrupt-controller; | 182 | interrupt-controller; |
183 | #interrupt-cells = <2>; | 183 | #interrupt-cells = <2>; |
184 | reg = <0x481ac000 0x1000>; | 184 | reg = <0x481ac000 0x1000>; |
185 | interrupts = <32>; | 185 | interrupts = <32>; |
186 | }; | 186 | }; |
187 | 187 | ||
188 | gpio3: gpio@481ae000 { | 188 | gpio3: gpio@481ae000 { |
189 | compatible = "ti,omap4-gpio"; | 189 | compatible = "ti,omap4-gpio"; |
190 | ti,hwmods = "gpio4"; | 190 | ti,hwmods = "gpio4"; |
191 | gpio-controller; | 191 | gpio-controller; |
192 | #gpio-cells = <2>; | 192 | #gpio-cells = <2>; |
193 | interrupt-controller; | 193 | interrupt-controller; |
194 | #interrupt-cells = <2>; | 194 | #interrupt-cells = <2>; |
195 | reg = <0x481ae000 0x1000>; | 195 | reg = <0x481ae000 0x1000>; |
196 | interrupts = <62>; | 196 | interrupts = <62>; |
197 | }; | 197 | }; |
198 | 198 | ||
199 | uart0: serial@44e09000 { | 199 | uart0: serial@44e09000 { |
200 | compatible = "ti,omap3-uart"; | 200 | compatible = "ti,omap3-uart"; |
201 | ti,hwmods = "uart1"; | 201 | ti,hwmods = "uart1"; |
202 | clock-frequency = <48000000>; | 202 | clock-frequency = <48000000>; |
203 | reg = <0x44e09000 0x2000>; | 203 | reg = <0x44e09000 0x2000>; |
204 | interrupts = <72>; | 204 | interrupts = <72>; |
205 | status = "disabled"; | 205 | status = "disabled"; |
206 | }; | 206 | }; |
207 | 207 | ||
208 | uart1: serial@48022000 { | 208 | uart1: serial@48022000 { |
209 | compatible = "ti,omap3-uart"; | 209 | compatible = "ti,omap3-uart"; |
210 | ti,hwmods = "uart2"; | 210 | ti,hwmods = "uart2"; |
211 | clock-frequency = <48000000>; | 211 | clock-frequency = <48000000>; |
212 | reg = <0x48022000 0x2000>; | 212 | reg = <0x48022000 0x2000>; |
213 | interrupts = <73>; | 213 | interrupts = <73>; |
214 | status = "disabled"; | 214 | status = "disabled"; |
215 | }; | 215 | }; |
216 | 216 | ||
217 | uart2: serial@48024000 { | 217 | uart2: serial@48024000 { |
218 | compatible = "ti,omap3-uart"; | 218 | compatible = "ti,omap3-uart"; |
219 | ti,hwmods = "uart3"; | 219 | ti,hwmods = "uart3"; |
220 | clock-frequency = <48000000>; | 220 | clock-frequency = <48000000>; |
221 | reg = <0x48024000 0x2000>; | 221 | reg = <0x48024000 0x2000>; |
222 | interrupts = <74>; | 222 | interrupts = <74>; |
223 | status = "disabled"; | 223 | status = "disabled"; |
224 | }; | 224 | }; |
225 | 225 | ||
226 | uart3: serial@481a6000 { | 226 | uart3: serial@481a6000 { |
227 | compatible = "ti,omap3-uart"; | 227 | compatible = "ti,omap3-uart"; |
228 | ti,hwmods = "uart4"; | 228 | ti,hwmods = "uart4"; |
229 | clock-frequency = <48000000>; | 229 | clock-frequency = <48000000>; |
230 | reg = <0x481a6000 0x2000>; | 230 | reg = <0x481a6000 0x2000>; |
231 | interrupts = <44>; | 231 | interrupts = <44>; |
232 | status = "disabled"; | 232 | status = "disabled"; |
233 | }; | 233 | }; |
234 | 234 | ||
235 | uart4: serial@481a8000 { | 235 | uart4: serial@481a8000 { |
236 | compatible = "ti,omap3-uart"; | 236 | compatible = "ti,omap3-uart"; |
237 | ti,hwmods = "uart5"; | 237 | ti,hwmods = "uart5"; |
238 | clock-frequency = <48000000>; | 238 | clock-frequency = <48000000>; |
239 | reg = <0x481a8000 0x2000>; | 239 | reg = <0x481a8000 0x2000>; |
240 | interrupts = <45>; | 240 | interrupts = <45>; |
241 | status = "disabled"; | 241 | status = "disabled"; |
242 | }; | 242 | }; |
243 | 243 | ||
244 | uart5: serial@481aa000 { | 244 | uart5: serial@481aa000 { |
245 | compatible = "ti,omap3-uart"; | 245 | compatible = "ti,omap3-uart"; |
246 | ti,hwmods = "uart6"; | 246 | ti,hwmods = "uart6"; |
247 | clock-frequency = <48000000>; | 247 | clock-frequency = <48000000>; |
248 | reg = <0x481aa000 0x2000>; | 248 | reg = <0x481aa000 0x2000>; |
249 | interrupts = <46>; | 249 | interrupts = <46>; |
250 | status = "disabled"; | 250 | status = "disabled"; |
251 | }; | 251 | }; |
252 | 252 | ||
253 | i2c0: i2c@44e0b000 { | 253 | i2c0: i2c@44e0b000 { |
254 | compatible = "ti,omap4-i2c"; | 254 | compatible = "ti,omap4-i2c"; |
255 | #address-cells = <1>; | 255 | #address-cells = <1>; |
256 | #size-cells = <0>; | 256 | #size-cells = <0>; |
257 | ti,hwmods = "i2c1"; | 257 | ti,hwmods = "i2c1"; |
258 | reg = <0x44e0b000 0x1000>; | 258 | reg = <0x44e0b000 0x1000>; |
259 | interrupts = <70>; | 259 | interrupts = <70>; |
260 | status = "disabled"; | 260 | status = "disabled"; |
261 | }; | 261 | }; |
262 | 262 | ||
263 | i2c1: i2c@4802a000 { | 263 | i2c1: i2c@4802a000 { |
264 | compatible = "ti,omap4-i2c"; | 264 | compatible = "ti,omap4-i2c"; |
265 | #address-cells = <1>; | 265 | #address-cells = <1>; |
266 | #size-cells = <0>; | 266 | #size-cells = <0>; |
267 | ti,hwmods = "i2c2"; | 267 | ti,hwmods = "i2c2"; |
268 | reg = <0x4802a000 0x1000>; | 268 | reg = <0x4802a000 0x1000>; |
269 | interrupts = <71>; | 269 | interrupts = <71>; |
270 | status = "disabled"; | 270 | status = "disabled"; |
271 | }; | 271 | }; |
272 | 272 | ||
273 | i2c2: i2c@4819c000 { | 273 | i2c2: i2c@4819c000 { |
274 | compatible = "ti,omap4-i2c"; | 274 | compatible = "ti,omap4-i2c"; |
275 | #address-cells = <1>; | 275 | #address-cells = <1>; |
276 | #size-cells = <0>; | 276 | #size-cells = <0>; |
277 | ti,hwmods = "i2c3"; | 277 | ti,hwmods = "i2c3"; |
278 | reg = <0x4819c000 0x1000>; | 278 | reg = <0x4819c000 0x1000>; |
279 | interrupts = <30>; | 279 | interrupts = <30>; |
280 | status = "disabled"; | 280 | status = "disabled"; |
281 | }; | 281 | }; |
282 | 282 | ||
283 | mmc1: mmc@48060000 { | 283 | mmc1: mmc@48060000 { |
284 | compatible = "ti,omap4-hsmmc"; | 284 | compatible = "ti,omap4-hsmmc"; |
285 | ti,hwmods = "mmc1"; | 285 | ti,hwmods = "mmc1"; |
286 | ti,dual-volt; | 286 | ti,dual-volt; |
287 | ti,needs-special-reset; | 287 | ti,needs-special-reset; |
288 | ti,needs-special-hs-handling; | 288 | ti,needs-special-hs-handling; |
289 | dmas = <&edma 24 | 289 | dmas = <&edma 24 |
290 | &edma 25>; | 290 | &edma 25>; |
291 | dma-names = "tx", "rx"; | 291 | dma-names = "tx", "rx"; |
292 | interrupts = <64>; | 292 | interrupts = <64>; |
293 | interrupt-parent = <&intc>; | 293 | interrupt-parent = <&intc>; |
294 | reg = <0x48060000 0x1000>; | 294 | reg = <0x48060000 0x1000>; |
295 | status = "disabled"; | 295 | status = "disabled"; |
296 | }; | 296 | }; |
297 | 297 | ||
298 | mmc2: mmc@481d8000 { | 298 | mmc2: mmc@481d8000 { |
299 | compatible = "ti,omap4-hsmmc"; | 299 | compatible = "ti,omap4-hsmmc"; |
300 | ti,hwmods = "mmc2"; | 300 | ti,hwmods = "mmc2"; |
301 | ti,needs-special-reset; | 301 | ti,needs-special-reset; |
302 | dmas = <&edma 2 | 302 | dmas = <&edma 2 |
303 | &edma 3>; | 303 | &edma 3>; |
304 | dma-names = "tx", "rx"; | 304 | dma-names = "tx", "rx"; |
305 | interrupts = <28>; | 305 | interrupts = <28>; |
306 | interrupt-parent = <&intc>; | 306 | interrupt-parent = <&intc>; |
307 | reg = <0x481d8000 0x1000>; | 307 | reg = <0x481d8000 0x1000>; |
308 | status = "disabled"; | 308 | status = "disabled"; |
309 | }; | 309 | }; |
310 | 310 | ||
311 | mmc3: mmc@47810000 { | 311 | mmc3: mmc@47810000 { |
312 | compatible = "ti,omap4-hsmmc"; | 312 | compatible = "ti,omap4-hsmmc"; |
313 | ti,hwmods = "mmc3"; | 313 | ti,hwmods = "mmc3"; |
314 | ti,needs-special-reset; | 314 | ti,needs-special-reset; |
315 | interrupts = <29>; | 315 | interrupts = <29>; |
316 | interrupt-parent = <&intc>; | 316 | interrupt-parent = <&intc>; |
317 | reg = <0x47810000 0x1000>; | 317 | reg = <0x47810000 0x1000>; |
318 | status = "disabled"; | 318 | status = "disabled"; |
319 | }; | 319 | }; |
320 | 320 | ||
321 | hwspinlock: spinlock@480ca000 { | 321 | hwspinlock: spinlock@480ca000 { |
322 | compatible = "ti,omap4-hwspinlock"; | 322 | compatible = "ti,omap4-hwspinlock"; |
323 | reg = <0x480ca000 0x1000>; | 323 | reg = <0x480ca000 0x1000>; |
324 | ti,hwmods = "spinlock"; | 324 | ti,hwmods = "spinlock"; |
325 | #hwlock-cells = <1>; | 325 | #hwlock-cells = <1>; |
326 | }; | 326 | }; |
327 | 327 | ||
328 | wdt2: wdt@44e35000 { | 328 | wdt2: wdt@44e35000 { |
329 | compatible = "ti,omap3-wdt"; | 329 | compatible = "ti,omap3-wdt"; |
330 | ti,hwmods = "wd_timer2"; | 330 | ti,hwmods = "wd_timer2"; |
331 | reg = <0x44e35000 0x1000>; | 331 | reg = <0x44e35000 0x1000>; |
332 | interrupts = <91>; | 332 | interrupts = <91>; |
333 | }; | 333 | }; |
334 | 334 | ||
335 | dcan0: d_can@481cc000 { | 335 | dcan0: d_can@481cc000 { |
336 | compatible = "bosch,d_can"; | 336 | compatible = "bosch,d_can"; |
337 | ti,hwmods = "d_can0"; | 337 | ti,hwmods = "d_can0"; |
338 | reg = <0x481cc000 0x2000 | 338 | reg = <0x481cc000 0x2000 |
339 | 0x44e10644 0x4>; | 339 | 0x44e10644 0x4>; |
340 | interrupts = <52>; | 340 | interrupts = <52>; |
341 | status = "disabled"; | 341 | status = "disabled"; |
342 | }; | 342 | }; |
343 | 343 | ||
344 | dcan1: d_can@481d0000 { | 344 | dcan1: d_can@481d0000 { |
345 | compatible = "bosch,d_can"; | 345 | compatible = "bosch,d_can"; |
346 | ti,hwmods = "d_can1"; | 346 | ti,hwmods = "d_can1"; |
347 | reg = <0x481d0000 0x2000 | 347 | reg = <0x481d0000 0x2000 |
348 | 0x44e10644 0x4>; | 348 | 0x44e10644 0x4>; |
349 | interrupts = <55>; | 349 | interrupts = <55>; |
350 | status = "disabled"; | 350 | status = "disabled"; |
351 | }; | 351 | }; |
352 | 352 | ||
353 | timer1: timer@44e31000 { | 353 | timer1: timer@44e31000 { |
354 | compatible = "ti,am335x-timer-1ms"; | 354 | compatible = "ti,am335x-timer-1ms"; |
355 | reg = <0x44e31000 0x400>; | 355 | reg = <0x44e31000 0x400>; |
356 | interrupts = <67>; | 356 | interrupts = <67>; |
357 | ti,hwmods = "timer1"; | 357 | ti,hwmods = "timer1"; |
358 | ti,timer-alwon; | 358 | ti,timer-alwon; |
359 | }; | 359 | }; |
360 | 360 | ||
361 | timer2: timer@48040000 { | 361 | timer2: timer@48040000 { |
362 | compatible = "ti,am335x-timer"; | 362 | compatible = "ti,am335x-timer"; |
363 | reg = <0x48040000 0x400>; | 363 | reg = <0x48040000 0x400>; |
364 | interrupts = <68>; | 364 | interrupts = <68>; |
365 | ti,hwmods = "timer2"; | 365 | ti,hwmods = "timer2"; |
366 | }; | 366 | }; |
367 | 367 | ||
368 | timer3: timer@48042000 { | 368 | timer3: timer@48042000 { |
369 | compatible = "ti,am335x-timer"; | 369 | compatible = "ti,am335x-timer"; |
370 | reg = <0x48042000 0x400>; | 370 | reg = <0x48042000 0x400>; |
371 | interrupts = <69>; | 371 | interrupts = <69>; |
372 | ti,hwmods = "timer3"; | 372 | ti,hwmods = "timer3"; |
373 | }; | 373 | }; |
374 | 374 | ||
375 | timer4: timer@48044000 { | 375 | timer4: timer@48044000 { |
376 | compatible = "ti,am335x-timer"; | 376 | compatible = "ti,am335x-timer"; |
377 | reg = <0x48044000 0x400>; | 377 | reg = <0x48044000 0x400>; |
378 | interrupts = <92>; | 378 | interrupts = <92>; |
379 | ti,hwmods = "timer4"; | 379 | ti,hwmods = "timer4"; |
380 | ti,timer-pwm; | 380 | ti,timer-pwm; |
381 | }; | 381 | }; |
382 | 382 | ||
383 | timer5: timer@48046000 { | 383 | timer5: timer@48046000 { |
384 | compatible = "ti,am335x-timer"; | 384 | compatible = "ti,am335x-timer"; |
385 | reg = <0x48046000 0x400>; | 385 | reg = <0x48046000 0x400>; |
386 | interrupts = <93>; | 386 | interrupts = <93>; |
387 | ti,hwmods = "timer5"; | 387 | ti,hwmods = "timer5"; |
388 | ti,timer-pwm; | 388 | ti,timer-pwm; |
389 | }; | 389 | }; |
390 | 390 | ||
391 | timer6: timer@48048000 { | 391 | timer6: timer@48048000 { |
392 | compatible = "ti,am335x-timer"; | 392 | compatible = "ti,am335x-timer"; |
393 | reg = <0x48048000 0x400>; | 393 | reg = <0x48048000 0x400>; |
394 | interrupts = <94>; | 394 | interrupts = <94>; |
395 | ti,hwmods = "timer6"; | 395 | ti,hwmods = "timer6"; |
396 | ti,timer-pwm; | 396 | ti,timer-pwm; |
397 | }; | 397 | }; |
398 | 398 | ||
399 | timer7: timer@4804a000 { | 399 | timer7: timer@4804a000 { |
400 | compatible = "ti,am335x-timer"; | 400 | compatible = "ti,am335x-timer"; |
401 | reg = <0x4804a000 0x400>; | 401 | reg = <0x4804a000 0x400>; |
402 | interrupts = <95>; | 402 | interrupts = <95>; |
403 | ti,hwmods = "timer7"; | 403 | ti,hwmods = "timer7"; |
404 | ti,timer-pwm; | 404 | ti,timer-pwm; |
405 | }; | 405 | }; |
406 | 406 | ||
407 | rtc: rtc@44e3e000 { | 407 | rtc: rtc@44e3e000 { |
408 | compatible = "ti,da830-rtc"; | 408 | compatible = "ti,da830-rtc"; |
409 | reg = <0x44e3e000 0x1000>; | 409 | reg = <0x44e3e000 0x1000>; |
410 | interrupts = <75 | 410 | interrupts = <75 |
411 | 76>; | 411 | 76>; |
412 | ti,hwmods = "rtc"; | 412 | ti,hwmods = "rtc"; |
413 | }; | 413 | }; |
414 | 414 | ||
415 | spi0: spi@48030000 { | 415 | spi0: spi@48030000 { |
416 | compatible = "ti,omap4-mcspi"; | 416 | compatible = "ti,omap4-mcspi"; |
417 | #address-cells = <1>; | 417 | #address-cells = <1>; |
418 | #size-cells = <0>; | 418 | #size-cells = <0>; |
419 | reg = <0x48030000 0x400>; | 419 | reg = <0x48030000 0x400>; |
420 | interrupts = <65>; | 420 | interrupts = <65>; |
421 | ti,spi-num-cs = <2>; | 421 | ti,spi-num-cs = <2>; |
422 | ti,hwmods = "spi0"; | 422 | ti,hwmods = "spi0"; |
423 | dmas = <&edma 16 | 423 | dmas = <&edma 16 |
424 | &edma 17 | 424 | &edma 17 |
425 | &edma 18 | 425 | &edma 18 |
426 | &edma 19>; | 426 | &edma 19>; |
427 | dma-names = "tx0", "rx0", "tx1", "rx1"; | 427 | dma-names = "tx0", "rx0", "tx1", "rx1"; |
428 | status = "disabled"; | 428 | status = "disabled"; |
429 | }; | 429 | }; |
430 | 430 | ||
431 | spi1: spi@481a0000 { | 431 | spi1: spi@481a0000 { |
432 | compatible = "ti,omap4-mcspi"; | 432 | compatible = "ti,omap4-mcspi"; |
433 | #address-cells = <1>; | 433 | #address-cells = <1>; |
434 | #size-cells = <0>; | 434 | #size-cells = <0>; |
435 | reg = <0x481a0000 0x400>; | 435 | reg = <0x481a0000 0x400>; |
436 | interrupts = <125>; | 436 | interrupts = <125>; |
437 | ti,spi-num-cs = <2>; | 437 | ti,spi-num-cs = <2>; |
438 | ti,hwmods = "spi1"; | 438 | ti,hwmods = "spi1"; |
439 | dmas = <&edma 42 | 439 | dmas = <&edma 42 |
440 | &edma 43 | 440 | &edma 43 |
441 | &edma 44 | 441 | &edma 44 |
442 | &edma 45>; | 442 | &edma 45>; |
443 | dma-names = "tx0", "rx0", "tx1", "rx1"; | 443 | dma-names = "tx0", "rx0", "tx1", "rx1"; |
444 | status = "disabled"; | 444 | status = "disabled"; |
445 | }; | 445 | }; |
446 | 446 | ||
447 | usb: usb@47400000 { | 447 | usb: usb@47400000 { |
448 | compatible = "ti,am33xx-usb"; | 448 | compatible = "ti,am33xx-usb"; |
449 | reg = <0x47400000 0x1000>; | 449 | reg = <0x47400000 0x1000>; |
450 | ranges; | 450 | ranges; |
451 | #address-cells = <1>; | 451 | #address-cells = <1>; |
452 | #size-cells = <1>; | 452 | #size-cells = <1>; |
453 | ti,hwmods = "usb_otg_hs"; | 453 | ti,hwmods = "usb_otg_hs"; |
454 | status = "disabled"; | 454 | status = "disabled"; |
455 | 455 | ||
456 | usb_ctrl_mod: control@44e10620 { | 456 | usb_ctrl_mod: control@44e10620 { |
457 | compatible = "ti,am335x-usb-ctrl-module"; | 457 | compatible = "ti,am335x-usb-ctrl-module"; |
458 | reg = <0x44e10620 0x10 | 458 | reg = <0x44e10620 0x10 |
459 | 0x44e10648 0x4>; | 459 | 0x44e10648 0x4>; |
460 | reg-names = "phy_ctrl", "wakeup"; | 460 | reg-names = "phy_ctrl", "wakeup"; |
461 | status = "disabled"; | 461 | status = "disabled"; |
462 | }; | 462 | }; |
463 | 463 | ||
464 | usb0_phy: usb-phy@47401300 { | 464 | usb0_phy: usb-phy@47401300 { |
465 | compatible = "ti,am335x-usb-phy"; | 465 | compatible = "ti,am335x-usb-phy"; |
466 | reg = <0x47401300 0x100>; | 466 | reg = <0x47401300 0x100>; |
467 | reg-names = "phy"; | 467 | reg-names = "phy"; |
468 | status = "disabled"; | 468 | status = "disabled"; |
469 | ti,ctrl_mod = <&usb_ctrl_mod>; | 469 | ti,ctrl_mod = <&usb_ctrl_mod>; |
470 | }; | 470 | }; |
471 | 471 | ||
472 | usb0: usb@47401000 { | 472 | usb0: usb@47401000 { |
473 | compatible = "ti,musb-am33xx"; | 473 | compatible = "ti,musb-am33xx"; |
474 | status = "disabled"; | 474 | status = "disabled"; |
475 | reg = <0x47401400 0x400 | 475 | reg = <0x47401400 0x400 |
476 | 0x47401000 0x200>; | 476 | 0x47401000 0x200>; |
477 | reg-names = "mc", "control"; | 477 | reg-names = "mc", "control"; |
478 | 478 | ||
479 | interrupts = <18>; | 479 | interrupts = <18>; |
480 | interrupt-names = "mc"; | 480 | interrupt-names = "mc"; |
481 | dr_mode = "otg"; | 481 | dr_mode = "otg"; |
482 | mentor,multipoint = <1>; | 482 | mentor,multipoint = <1>; |
483 | mentor,num-eps = <16>; | 483 | mentor,num-eps = <16>; |
484 | mentor,ram-bits = <12>; | 484 | mentor,ram-bits = <12>; |
485 | mentor,power = <500>; | 485 | mentor,power = <500>; |
486 | phys = <&usb0_phy>; | 486 | phys = <&usb0_phy>; |
487 | 487 | ||
488 | dmas = <&cppi41dma 0 0 &cppi41dma 1 0 | 488 | dmas = <&cppi41dma 0 0 &cppi41dma 1 0 |
489 | &cppi41dma 2 0 &cppi41dma 3 0 | 489 | &cppi41dma 2 0 &cppi41dma 3 0 |
490 | &cppi41dma 4 0 &cppi41dma 5 0 | 490 | &cppi41dma 4 0 &cppi41dma 5 0 |
491 | &cppi41dma 6 0 &cppi41dma 7 0 | 491 | &cppi41dma 6 0 &cppi41dma 7 0 |
492 | &cppi41dma 8 0 &cppi41dma 9 0 | 492 | &cppi41dma 8 0 &cppi41dma 9 0 |
493 | &cppi41dma 10 0 &cppi41dma 11 0 | 493 | &cppi41dma 10 0 &cppi41dma 11 0 |
494 | &cppi41dma 12 0 &cppi41dma 13 0 | 494 | &cppi41dma 12 0 &cppi41dma 13 0 |
495 | &cppi41dma 14 0 &cppi41dma 0 1 | 495 | &cppi41dma 14 0 &cppi41dma 0 1 |
496 | &cppi41dma 1 1 &cppi41dma 2 1 | 496 | &cppi41dma 1 1 &cppi41dma 2 1 |
497 | &cppi41dma 3 1 &cppi41dma 4 1 | 497 | &cppi41dma 3 1 &cppi41dma 4 1 |
498 | &cppi41dma 5 1 &cppi41dma 6 1 | 498 | &cppi41dma 5 1 &cppi41dma 6 1 |
499 | &cppi41dma 7 1 &cppi41dma 8 1 | 499 | &cppi41dma 7 1 &cppi41dma 8 1 |
500 | &cppi41dma 9 1 &cppi41dma 10 1 | 500 | &cppi41dma 9 1 &cppi41dma 10 1 |
501 | &cppi41dma 11 1 &cppi41dma 12 1 | 501 | &cppi41dma 11 1 &cppi41dma 12 1 |
502 | &cppi41dma 13 1 &cppi41dma 14 1>; | 502 | &cppi41dma 13 1 &cppi41dma 14 1>; |
503 | dma-names = | 503 | dma-names = |
504 | "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7", | 504 | "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7", |
505 | "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", | 505 | "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", |
506 | "rx14", "rx15", | 506 | "rx14", "rx15", |
507 | "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", | 507 | "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", |
508 | "tx8", "tx9", "tx10", "tx11", "tx12", "tx13", | 508 | "tx8", "tx9", "tx10", "tx11", "tx12", "tx13", |
509 | "tx14", "tx15"; | 509 | "tx14", "tx15"; |
510 | }; | 510 | }; |
511 | 511 | ||
512 | usb1_phy: usb-phy@47401b00 { | 512 | usb1_phy: usb-phy@47401b00 { |
513 | compatible = "ti,am335x-usb-phy"; | 513 | compatible = "ti,am335x-usb-phy"; |
514 | reg = <0x47401b00 0x100>; | 514 | reg = <0x47401b00 0x100>; |
515 | reg-names = "phy"; | 515 | reg-names = "phy"; |
516 | status = "disabled"; | 516 | status = "disabled"; |
517 | ti,ctrl_mod = <&usb_ctrl_mod>; | 517 | ti,ctrl_mod = <&usb_ctrl_mod>; |
518 | }; | 518 | }; |
519 | 519 | ||
520 | usb1: usb@47401800 { | 520 | usb1: usb@47401800 { |
521 | compatible = "ti,musb-am33xx"; | 521 | compatible = "ti,musb-am33xx"; |
522 | status = "disabled"; | 522 | status = "disabled"; |
523 | reg = <0x47401c00 0x400 | 523 | reg = <0x47401c00 0x400 |
524 | 0x47401800 0x200>; | 524 | 0x47401800 0x200>; |
525 | reg-names = "mc", "control"; | 525 | reg-names = "mc", "control"; |
526 | interrupts = <19>; | 526 | interrupts = <19>; |
527 | interrupt-names = "mc"; | 527 | interrupt-names = "mc"; |
528 | dr_mode = "otg"; | 528 | dr_mode = "otg"; |
529 | mentor,multipoint = <1>; | 529 | mentor,multipoint = <1>; |
530 | mentor,num-eps = <16>; | 530 | mentor,num-eps = <16>; |
531 | mentor,ram-bits = <12>; | 531 | mentor,ram-bits = <12>; |
532 | mentor,power = <500>; | 532 | mentor,power = <500>; |
533 | phys = <&usb1_phy>; | 533 | phys = <&usb1_phy>; |
534 | 534 | ||
535 | dmas = <&cppi41dma 15 0 &cppi41dma 16 0 | 535 | dmas = <&cppi41dma 15 0 &cppi41dma 16 0 |
536 | &cppi41dma 17 0 &cppi41dma 18 0 | 536 | &cppi41dma 17 0 &cppi41dma 18 0 |
537 | &cppi41dma 19 0 &cppi41dma 20 0 | 537 | &cppi41dma 19 0 &cppi41dma 20 0 |
538 | &cppi41dma 21 0 &cppi41dma 22 0 | 538 | &cppi41dma 21 0 &cppi41dma 22 0 |
539 | &cppi41dma 23 0 &cppi41dma 24 0 | 539 | &cppi41dma 23 0 &cppi41dma 24 0 |
540 | &cppi41dma 25 0 &cppi41dma 26 0 | 540 | &cppi41dma 25 0 &cppi41dma 26 0 |
541 | &cppi41dma 27 0 &cppi41dma 28 0 | 541 | &cppi41dma 27 0 &cppi41dma 28 0 |
542 | &cppi41dma 29 0 &cppi41dma 15 1 | 542 | &cppi41dma 29 0 &cppi41dma 15 1 |
543 | &cppi41dma 16 1 &cppi41dma 17 1 | 543 | &cppi41dma 16 1 &cppi41dma 17 1 |
544 | &cppi41dma 18 1 &cppi41dma 19 1 | 544 | &cppi41dma 18 1 &cppi41dma 19 1 |
545 | &cppi41dma 20 1 &cppi41dma 21 1 | 545 | &cppi41dma 20 1 &cppi41dma 21 1 |
546 | &cppi41dma 22 1 &cppi41dma 23 1 | 546 | &cppi41dma 22 1 &cppi41dma 23 1 |
547 | &cppi41dma 24 1 &cppi41dma 25 1 | 547 | &cppi41dma 24 1 &cppi41dma 25 1 |
548 | &cppi41dma 26 1 &cppi41dma 27 1 | 548 | &cppi41dma 26 1 &cppi41dma 27 1 |
549 | &cppi41dma 28 1 &cppi41dma 29 1>; | 549 | &cppi41dma 28 1 &cppi41dma 29 1>; |
550 | dma-names = | 550 | dma-names = |
551 | "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7", | 551 | "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7", |
552 | "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", | 552 | "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", |
553 | "rx14", "rx15", | 553 | "rx14", "rx15", |
554 | "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", | 554 | "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", |
555 | "tx8", "tx9", "tx10", "tx11", "tx12", "tx13", | 555 | "tx8", "tx9", "tx10", "tx11", "tx12", "tx13", |
556 | "tx14", "tx15"; | 556 | "tx14", "tx15"; |
557 | }; | 557 | }; |
558 | 558 | ||
559 | cppi41dma: dma-controller@47402000 { | 559 | cppi41dma: dma-controller@47402000 { |
560 | compatible = "ti,am3359-cppi41"; | 560 | compatible = "ti,am3359-cppi41"; |
561 | reg = <0x47400000 0x1000 | 561 | reg = <0x47400000 0x1000 |
562 | 0x47402000 0x1000 | 562 | 0x47402000 0x1000 |
563 | 0x47403000 0x1000 | 563 | 0x47403000 0x1000 |
564 | 0x47404000 0x4000>; | 564 | 0x47404000 0x4000>; |
565 | reg-names = "glue", "controller", "scheduler", "queuemgr"; | 565 | reg-names = "glue", "controller", "scheduler", "queuemgr"; |
566 | interrupts = <17>; | 566 | interrupts = <17>; |
567 | interrupt-names = "glue"; | 567 | interrupt-names = "glue"; |
568 | #dma-cells = <2>; | 568 | #dma-cells = <2>; |
569 | #dma-channels = <30>; | 569 | #dma-channels = <30>; |
570 | #dma-requests = <256>; | 570 | #dma-requests = <256>; |
571 | status = "disabled"; | 571 | status = "disabled"; |
572 | }; | 572 | }; |
573 | }; | 573 | }; |
574 | 574 | ||
575 | epwmss0: epwmss@48300000 { | 575 | epwmss0: epwmss@48300000 { |
576 | compatible = "ti,am33xx-pwmss"; | 576 | compatible = "ti,am33xx-pwmss"; |
577 | reg = <0x48300000 0x10>; | 577 | reg = <0x48300000 0x10>; |
578 | ti,hwmods = "epwmss0"; | 578 | ti,hwmods = "epwmss0"; |
579 | #address-cells = <1>; | 579 | #address-cells = <1>; |
580 | #size-cells = <1>; | 580 | #size-cells = <1>; |
581 | status = "disabled"; | 581 | status = "disabled"; |
582 | ranges = <0x48300100 0x48300100 0x80 /* ECAP */ | 582 | ranges = <0x48300100 0x48300100 0x80 /* ECAP */ |
583 | 0x48300180 0x48300180 0x80 /* EQEP */ | 583 | 0x48300180 0x48300180 0x80 /* EQEP */ |
584 | 0x48300200 0x48300200 0x80>; /* EHRPWM */ | 584 | 0x48300200 0x48300200 0x80>; /* EHRPWM */ |
585 | 585 | ||
586 | ecap0: ecap@48300100 { | 586 | ecap0: ecap@48300100 { |
587 | compatible = "ti,am33xx-ecap"; | 587 | compatible = "ti,am33xx-ecap"; |
588 | #pwm-cells = <3>; | 588 | #pwm-cells = <3>; |
589 | reg = <0x48300100 0x80>; | 589 | reg = <0x48300100 0x80>; |
590 | interrupts = <31>; | 590 | interrupts = <31>; |
591 | interrupt-names = "ecap0"; | 591 | interrupt-names = "ecap0"; |
592 | ti,hwmods = "ecap0"; | 592 | ti,hwmods = "ecap0"; |
593 | status = "disabled"; | 593 | status = "disabled"; |
594 | }; | 594 | }; |
595 | 595 | ||
596 | ehrpwm0: ehrpwm@48300200 { | 596 | ehrpwm0: ehrpwm@48300200 { |
597 | compatible = "ti,am33xx-ehrpwm"; | 597 | compatible = "ti,am33xx-ehrpwm"; |
598 | #pwm-cells = <3>; | 598 | #pwm-cells = <3>; |
599 | reg = <0x48300200 0x80>; | 599 | reg = <0x48300200 0x80>; |
600 | ti,hwmods = "ehrpwm0"; | 600 | ti,hwmods = "ehrpwm0"; |
601 | status = "disabled"; | 601 | status = "disabled"; |
602 | }; | 602 | }; |
603 | }; | 603 | }; |
604 | 604 | ||
605 | epwmss1: epwmss@48302000 { | 605 | epwmss1: epwmss@48302000 { |
606 | compatible = "ti,am33xx-pwmss"; | 606 | compatible = "ti,am33xx-pwmss"; |
607 | reg = <0x48302000 0x10>; | 607 | reg = <0x48302000 0x10>; |
608 | ti,hwmods = "epwmss1"; | 608 | ti,hwmods = "epwmss1"; |
609 | #address-cells = <1>; | 609 | #address-cells = <1>; |
610 | #size-cells = <1>; | 610 | #size-cells = <1>; |
611 | status = "disabled"; | 611 | status = "disabled"; |
612 | ranges = <0x48302100 0x48302100 0x80 /* ECAP */ | 612 | ranges = <0x48302100 0x48302100 0x80 /* ECAP */ |
613 | 0x48302180 0x48302180 0x80 /* EQEP */ | 613 | 0x48302180 0x48302180 0x80 /* EQEP */ |
614 | 0x48302200 0x48302200 0x80>; /* EHRPWM */ | 614 | 0x48302200 0x48302200 0x80>; /* EHRPWM */ |
615 | 615 | ||
616 | ecap1: ecap@48302100 { | 616 | ecap1: ecap@48302100 { |
617 | compatible = "ti,am33xx-ecap"; | 617 | compatible = "ti,am33xx-ecap"; |
618 | #pwm-cells = <3>; | 618 | #pwm-cells = <3>; |
619 | reg = <0x48302100 0x80>; | 619 | reg = <0x48302100 0x80>; |
620 | interrupts = <47>; | 620 | interrupts = <47>; |
621 | interrupt-names = "ecap1"; | 621 | interrupt-names = "ecap1"; |
622 | ti,hwmods = "ecap1"; | 622 | ti,hwmods = "ecap1"; |
623 | status = "disabled"; | 623 | status = "disabled"; |
624 | }; | 624 | }; |
625 | 625 | ||
626 | ehrpwm1: ehrpwm@48302200 { | 626 | ehrpwm1: ehrpwm@48302200 { |
627 | compatible = "ti,am33xx-ehrpwm"; | 627 | compatible = "ti,am33xx-ehrpwm"; |
628 | #pwm-cells = <3>; | 628 | #pwm-cells = <3>; |
629 | reg = <0x48302200 0x80>; | 629 | reg = <0x48302200 0x80>; |
630 | ti,hwmods = "ehrpwm1"; | 630 | ti,hwmods = "ehrpwm1"; |
631 | status = "disabled"; | 631 | status = "disabled"; |
632 | }; | 632 | }; |
633 | }; | 633 | }; |
634 | 634 | ||
635 | epwmss2: epwmss@48304000 { | 635 | epwmss2: epwmss@48304000 { |
636 | compatible = "ti,am33xx-pwmss"; | 636 | compatible = "ti,am33xx-pwmss"; |
637 | reg = <0x48304000 0x10>; | 637 | reg = <0x48304000 0x10>; |
638 | ti,hwmods = "epwmss2"; | 638 | ti,hwmods = "epwmss2"; |
639 | #address-cells = <1>; | 639 | #address-cells = <1>; |
640 | #size-cells = <1>; | 640 | #size-cells = <1>; |
641 | status = "disabled"; | 641 | status = "disabled"; |
642 | ranges = <0x48304100 0x48304100 0x80 /* ECAP */ | 642 | ranges = <0x48304100 0x48304100 0x80 /* ECAP */ |
643 | 0x48304180 0x48304180 0x80 /* EQEP */ | 643 | 0x48304180 0x48304180 0x80 /* EQEP */ |
644 | 0x48304200 0x48304200 0x80>; /* EHRPWM */ | 644 | 0x48304200 0x48304200 0x80>; /* EHRPWM */ |
645 | 645 | ||
646 | ecap2: ecap@48304100 { | 646 | ecap2: ecap@48304100 { |
647 | compatible = "ti,am33xx-ecap"; | 647 | compatible = "ti,am33xx-ecap"; |
648 | #pwm-cells = <3>; | 648 | #pwm-cells = <3>; |
649 | reg = <0x48304100 0x80>; | 649 | reg = <0x48304100 0x80>; |
650 | interrupts = <61>; | 650 | interrupts = <61>; |
651 | interrupt-names = "ecap2"; | 651 | interrupt-names = "ecap2"; |
652 | ti,hwmods = "ecap2"; | 652 | ti,hwmods = "ecap2"; |
653 | status = "disabled"; | 653 | status = "disabled"; |
654 | }; | 654 | }; |
655 | 655 | ||
656 | ehrpwm2: ehrpwm@48304200 { | 656 | ehrpwm2: ehrpwm@48304200 { |
657 | compatible = "ti,am33xx-ehrpwm"; | 657 | compatible = "ti,am33xx-ehrpwm"; |
658 | #pwm-cells = <3>; | 658 | #pwm-cells = <3>; |
659 | reg = <0x48304200 0x80>; | 659 | reg = <0x48304200 0x80>; |
660 | ti,hwmods = "ehrpwm2"; | 660 | ti,hwmods = "ehrpwm2"; |
661 | status = "disabled"; | 661 | status = "disabled"; |
662 | }; | 662 | }; |
663 | }; | 663 | }; |
664 | 664 | ||
665 | mac: ethernet@4a100000 { | 665 | mac: ethernet@4a100000 { |
666 | compatible = "ti,cpsw"; | 666 | compatible = "ti,cpsw"; |
667 | ti,hwmods = "cpgmac0"; | 667 | ti,hwmods = "cpgmac0"; |
668 | cpdma_channels = <8>; | 668 | cpdma_channels = <8>; |
669 | ale_entries = <1024>; | 669 | ale_entries = <1024>; |
670 | bd_ram_size = <0x2000>; | 670 | bd_ram_size = <0x2000>; |
671 | no_bd_ram = <0>; | 671 | no_bd_ram = <0>; |
672 | rx_descs = <64>; | 672 | rx_descs = <64>; |
673 | mac_control = <0x20>; | 673 | mac_control = <0x20>; |
674 | slaves = <2>; | 674 | slaves = <2>; |
675 | active_slave = <0>; | 675 | active_slave = <0>; |
676 | cpts_clock_mult = <0x80000000>; | 676 | cpts_clock_mult = <0x80000000>; |
677 | cpts_clock_shift = <29>; | 677 | cpts_clock_shift = <29>; |
678 | reg = <0x4a100000 0x800 | 678 | reg = <0x4a100000 0x800 |
679 | 0x4a101200 0x100>; | 679 | 0x4a101200 0x100>; |
680 | #address-cells = <1>; | 680 | #address-cells = <1>; |
681 | #size-cells = <1>; | 681 | #size-cells = <1>; |
682 | interrupt-parent = <&intc>; | 682 | interrupt-parent = <&intc>; |
683 | /* | 683 | /* |
684 | * c0_rx_thresh_pend | 684 | * c0_rx_thresh_pend |
685 | * c0_rx_pend | 685 | * c0_rx_pend |
686 | * c0_tx_pend | 686 | * c0_tx_pend |
687 | * c0_misc_pend | 687 | * c0_misc_pend |
688 | */ | 688 | */ |
689 | interrupts = <40 41 42 43>; | 689 | interrupts = <40 41 42 43>; |
690 | ranges; | 690 | ranges; |
691 | 691 | ||
692 | davinci_mdio: mdio@4a101000 { | 692 | davinci_mdio: mdio@4a101000 { |
693 | compatible = "ti,davinci_mdio"; | 693 | compatible = "ti,davinci_mdio"; |
694 | #address-cells = <1>; | 694 | #address-cells = <1>; |
695 | #size-cells = <0>; | 695 | #size-cells = <0>; |
696 | ti,hwmods = "davinci_mdio"; | 696 | ti,hwmods = "davinci_mdio"; |
697 | bus_freq = <1000000>; | 697 | bus_freq = <1000000>; |
698 | reg = <0x4a101000 0x100>; | 698 | reg = <0x4a101000 0x100>; |
699 | }; | 699 | }; |
700 | 700 | ||
701 | cpsw_emac0: slave@4a100200 { | 701 | cpsw_emac0: slave@4a100200 { |
702 | /* Filled in by U-Boot */ | 702 | /* Filled in by U-Boot */ |
703 | mac-address = [ 00 00 00 00 00 00 ]; | 703 | mac-address = [ 00 00 00 00 00 00 ]; |
704 | }; | 704 | }; |
705 | 705 | ||
706 | cpsw_emac1: slave@4a100300 { | 706 | cpsw_emac1: slave@4a100300 { |
707 | /* Filled in by U-Boot */ | 707 | /* Filled in by U-Boot */ |
708 | mac-address = [ 00 00 00 00 00 00 ]; | 708 | mac-address = [ 00 00 00 00 00 00 ]; |
709 | }; | 709 | }; |
710 | 710 | ||
711 | phy_sel: cpsw-phy-sel@44e10650 { | 711 | phy_sel: cpsw-phy-sel@44e10650 { |
712 | compatible = "ti,am3352-cpsw-phy-sel"; | 712 | compatible = "ti,am3352-cpsw-phy-sel"; |
713 | reg= <0x44e10650 0x4>; | 713 | reg= <0x44e10650 0x4>; |
714 | reg-names = "gmii-sel"; | 714 | reg-names = "gmii-sel"; |
715 | }; | 715 | }; |
716 | }; | 716 | }; |
717 | 717 | ||
718 | ocmcram: ocmcram@40300000 { | 718 | ocmcram: ocmcram@40300000 { |
719 | compatible = "ti,am3352-ocmcram"; | 719 | compatible = "ti,am3352-ocmcram"; |
720 | reg = <0x40300000 0x10000>; | 720 | reg = <0x40300000 0x10000>; |
721 | ti,hwmods = "ocmcram"; | 721 | ti,hwmods = "ocmcram"; |
722 | }; | 722 | }; |
723 | 723 | ||
724 | wkup_m3: wkup_m3@44d00000 { | 724 | wkup_m3: wkup_m3@44d00000 { |
725 | compatible = "ti,am3353-wkup-m3"; | 725 | compatible = "ti,am3353-wkup-m3"; |
726 | reg = <0x44d00000 0x4000 /* M3 UMEM */ | 726 | reg = <0x44d00000 0x4000 /* M3 UMEM */ |
727 | 0x44d80000 0x2000>; /* M3 DMEM */ | 727 | 0x44d80000 0x2000>; /* M3 DMEM */ |
728 | ti,hwmods = "wkup_m3"; | 728 | ti,hwmods = "wkup_m3"; |
729 | ti,no-reset-on-init; | 729 | ti,no-reset-on-init; |
730 | }; | 730 | }; |
731 | 731 | ||
732 | elm: elm@48080000 { | 732 | elm: elm@48080000 { |
733 | compatible = "ti,am3352-elm"; | 733 | compatible = "ti,am3352-elm"; |
734 | reg = <0x48080000 0x2000>; | 734 | reg = <0x48080000 0x2000>; |
735 | interrupts = <4>; | 735 | interrupts = <4>; |
736 | ti,hwmods = "elm"; | 736 | ti,hwmods = "elm"; |
737 | status = "disabled"; | 737 | status = "disabled"; |
738 | }; | 738 | }; |
739 | 739 | ||
740 | lcdc: lcdc@4830e000 { | 740 | lcdc: lcdc@4830e000 { |
741 | compatible = "ti,am33xx-tilcdc"; | 741 | compatible = "ti,am33xx-tilcdc"; |
742 | reg = <0x4830e000 0x1000>; | 742 | reg = <0x4830e000 0x1000>; |
743 | interrupt-parent = <&intc>; | 743 | interrupt-parent = <&intc>; |
744 | interrupts = <36>; | 744 | interrupts = <36>; |
745 | ti,hwmods = "lcdc"; | 745 | ti,hwmods = "lcdc"; |
746 | status = "disabled"; | 746 | status = "disabled"; |
747 | }; | 747 | }; |
748 | 748 | ||
749 | tscadc: tscadc@44e0d000 { | 749 | tscadc: tscadc@44e0d000 { |
750 | compatible = "ti,am3359-tscadc"; | 750 | compatible = "ti,am3359-tscadc"; |
751 | reg = <0x44e0d000 0x1000>; | 751 | reg = <0x44e0d000 0x1000>; |
752 | interrupt-parent = <&intc>; | 752 | interrupt-parent = <&intc>; |
753 | interrupts = <16>; | 753 | interrupts = <16>; |
754 | ti,hwmods = "adc_tsc"; | 754 | ti,hwmods = "adc_tsc"; |
755 | status = "disabled"; | 755 | status = "disabled"; |
756 | 756 | ||
757 | tsc { | 757 | tsc { |
758 | compatible = "ti,am3359-tsc"; | 758 | compatible = "ti,am3359-tsc"; |
759 | }; | 759 | }; |
760 | am335x_adc: adc { | 760 | am335x_adc: adc { |
761 | #io-channel-cells = <1>; | 761 | #io-channel-cells = <1>; |
762 | compatible = "ti,am3359-adc"; | 762 | compatible = "ti,am3359-adc"; |
763 | }; | 763 | }; |
764 | }; | 764 | }; |
765 | 765 | ||
766 | gpmc: gpmc@50000000 { | 766 | gpmc: gpmc@50000000 { |
767 | compatible = "ti,am3352-gpmc"; | 767 | compatible = "ti,am3352-gpmc"; |
768 | ti,hwmods = "gpmc"; | 768 | ti,hwmods = "gpmc"; |
769 | ti,no-idle-on-init; | 769 | ti,no-idle-on-init; |
770 | reg = <0x50000000 0x2000>; | 770 | reg = <0x50000000 0x2000>; |
771 | interrupts = <100>; | 771 | interrupts = <100>; |
772 | gpmc,num-cs = <7>; | 772 | gpmc,num-cs = <7>; |
773 | gpmc,num-waitpins = <2>; | 773 | gpmc,num-waitpins = <2>; |
774 | #address-cells = <2>; | 774 | #address-cells = <2>; |
775 | #size-cells = <1>; | 775 | #size-cells = <1>; |
776 | status = "disabled"; | 776 | status = "disabled"; |
777 | }; | 777 | }; |
778 | 778 | ||
779 | sham: sham@53100000 { | 779 | sham: sham@53100000 { |
780 | compatible = "ti,omap4-sham"; | 780 | compatible = "ti,omap4-sham"; |
781 | ti,hwmods = "sham"; | 781 | ti,hwmods = "sham"; |
782 | reg = <0x53100000 0x200>; | 782 | reg = <0x53100000 0x200>; |
783 | interrupts = <109>; | 783 | interrupts = <109>; |
784 | dmas = <&edma 36>; | 784 | dmas = <&edma 36>; |
785 | dma-names = "rx"; | 785 | dma-names = "rx"; |
786 | }; | 786 | }; |
787 | 787 | ||
788 | aes: aes@53500000 { | 788 | aes: aes@53500000 { |
789 | compatible = "ti,omap4-aes"; | 789 | compatible = "ti,omap4-aes"; |
790 | ti,hwmods = "aes"; | 790 | ti,hwmods = "aes"; |
791 | reg = <0x53500000 0xa0>; | 791 | reg = <0x53500000 0xa0>; |
792 | interrupts = <103>; | 792 | interrupts = <103>; |
793 | dmas = <&edma 6>, | 793 | dmas = <&edma 6>, |
794 | <&edma 5>; | 794 | <&edma 5>; |
795 | dma-names = "tx", "rx"; | 795 | dma-names = "tx", "rx"; |
796 | }; | 796 | }; |
797 | 797 | ||
798 | mcasp0: mcasp@48038000 { | 798 | mcasp0: mcasp@48038000 { |
799 | compatible = "ti,am33xx-mcasp-audio"; | 799 | compatible = "ti,am33xx-mcasp-audio"; |
800 | ti,hwmods = "mcasp0"; | 800 | ti,hwmods = "mcasp0"; |
801 | reg = <0x48038000 0x2000>, | 801 | reg = <0x48038000 0x2000>, |
802 | <0x46000000 0x400000>; | 802 | <0x46000000 0x400000>; |
803 | reg-names = "mpu", "dat"; | 803 | reg-names = "mpu", "dat"; |
804 | interrupts = <80>, <81>; | 804 | interrupts = <80>, <81>; |
805 | interrupts-names = "tx", "rx"; | 805 | interrupt-names = "tx", "rx"; |
806 | status = "disabled"; | 806 | status = "disabled"; |
807 | dmas = <&edma 8>, | 807 | dmas = <&edma 8>, |
808 | <&edma 9>; | 808 | <&edma 9>; |
809 | dma-names = "tx", "rx"; | 809 | dma-names = "tx", "rx"; |
810 | }; | 810 | }; |
811 | 811 | ||
812 | mcasp1: mcasp@4803C000 { | 812 | mcasp1: mcasp@4803C000 { |
813 | compatible = "ti,am33xx-mcasp-audio"; | 813 | compatible = "ti,am33xx-mcasp-audio"; |
814 | ti,hwmods = "mcasp1"; | 814 | ti,hwmods = "mcasp1"; |
815 | reg = <0x4803C000 0x2000>, | 815 | reg = <0x4803C000 0x2000>, |
816 | <0x46400000 0x400000>; | 816 | <0x46400000 0x400000>; |
817 | reg-names = "mpu", "dat"; | 817 | reg-names = "mpu", "dat"; |
818 | interrupts = <82>, <83>; | 818 | interrupts = <82>, <83>; |
819 | interrupts-names = "tx", "rx"; | 819 | interrupt-names = "tx", "rx"; |
820 | status = "disabled"; | 820 | status = "disabled"; |
821 | dmas = <&edma 10>, | 821 | dmas = <&edma 10>, |
822 | <&edma 11>; | 822 | <&edma 11>; |
823 | dma-names = "tx", "rx"; | 823 | dma-names = "tx", "rx"; |
824 | }; | 824 | }; |
825 | 825 | ||
826 | rng: rng@48310000 { | 826 | rng: rng@48310000 { |
827 | compatible = "ti,omap4-rng"; | 827 | compatible = "ti,omap4-rng"; |
828 | ti,hwmods = "rng"; | 828 | ti,hwmods = "rng"; |
829 | reg = <0x48310000 0x2000>; | 829 | reg = <0x48310000 0x2000>; |
830 | interrupts = <111>; | 830 | interrupts = <111>; |
831 | }; | 831 | }; |
832 | }; | 832 | }; |
833 | }; | 833 | }; |
834 | 834 | ||
835 | /include/ "am33xx-clocks.dtsi" | 835 | /include/ "am33xx-clocks.dtsi" |
836 | 836 |
arch/arm/boot/dts/am4372.dtsi
1 | /* | 1 | /* |
2 | * Device Tree Source for AM4372 SoC | 2 | * Device Tree Source for AM4372 SoC |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | 4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * | 5 | * |
6 | * This file is licensed under the terms of the GNU General Public License | 6 | * This file is licensed under the terms of the GNU General Public License |
7 | * version 2. This program is licensed "as is" without any warranty of any | 7 | * version 2. This program is licensed "as is" without any warranty of any |
8 | * kind, whether express or implied. | 8 | * kind, whether express or implied. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <dt-bindings/gpio/gpio.h> | 11 | #include <dt-bindings/gpio/gpio.h> |
12 | #include <dt-bindings/interrupt-controller/arm-gic.h> | 12 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
13 | 13 | ||
14 | #include "skeleton.dtsi" | 14 | #include "skeleton.dtsi" |
15 | 15 | ||
16 | / { | 16 | / { |
17 | compatible = "ti,am4372", "ti,am43"; | 17 | compatible = "ti,am4372", "ti,am43"; |
18 | interrupt-parent = <&gic>; | 18 | interrupt-parent = <&gic>; |
19 | 19 | ||
20 | 20 | ||
21 | aliases { | 21 | aliases { |
22 | i2c0 = &i2c0; | 22 | i2c0 = &i2c0; |
23 | i2c1 = &i2c1; | 23 | i2c1 = &i2c1; |
24 | i2c2 = &i2c2; | 24 | i2c2 = &i2c2; |
25 | serial0 = &uart0; | 25 | serial0 = &uart0; |
26 | ethernet0 = &cpsw_emac0; | 26 | ethernet0 = &cpsw_emac0; |
27 | ethernet1 = &cpsw_emac1; | 27 | ethernet1 = &cpsw_emac1; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | cpus { | 30 | cpus { |
31 | #address-cells = <1>; | 31 | #address-cells = <1>; |
32 | #size-cells = <0>; | 32 | #size-cells = <0>; |
33 | cpu@0 { | 33 | cpu@0 { |
34 | compatible = "arm,cortex-a9"; | 34 | compatible = "arm,cortex-a9"; |
35 | device_type = "cpu"; | 35 | device_type = "cpu"; |
36 | reg = <0>; | 36 | reg = <0>; |
37 | 37 | ||
38 | clocks = <&dpll_mpu_ck>; | 38 | clocks = <&dpll_mpu_ck>; |
39 | clock-names = "cpu"; | 39 | clock-names = "cpu"; |
40 | 40 | ||
41 | clock-latency = <300000>; /* From omap-cpufreq driver */ | 41 | clock-latency = <300000>; /* From omap-cpufreq driver */ |
42 | }; | 42 | }; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | gic: interrupt-controller@48241000 { | 45 | gic: interrupt-controller@48241000 { |
46 | compatible = "arm,cortex-a9-gic"; | 46 | compatible = "arm,cortex-a9-gic"; |
47 | interrupt-controller; | 47 | interrupt-controller; |
48 | #interrupt-cells = <3>; | 48 | #interrupt-cells = <3>; |
49 | reg = <0x48241000 0x1000>, | 49 | reg = <0x48241000 0x1000>, |
50 | <0x48240100 0x0100>; | 50 | <0x48240100 0x0100>; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | l2-cache-controller@48242000 { | 53 | l2-cache-controller@48242000 { |
54 | compatible = "arm,pl310-cache"; | 54 | compatible = "arm,pl310-cache"; |
55 | reg = <0x48242000 0x1000>; | 55 | reg = <0x48242000 0x1000>; |
56 | cache-unified; | 56 | cache-unified; |
57 | cache-level = <2>; | 57 | cache-level = <2>; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | am43xx_pinmux: pinmux@44e10800 { | 60 | am43xx_pinmux: pinmux@44e10800 { |
61 | compatible = "pinctrl-single"; | 61 | compatible = "pinctrl-single"; |
62 | reg = <0x44e10800 0x31c>; | 62 | reg = <0x44e10800 0x31c>; |
63 | #address-cells = <1>; | 63 | #address-cells = <1>; |
64 | #size-cells = <0>; | 64 | #size-cells = <0>; |
65 | pinctrl-single,register-width = <32>; | 65 | pinctrl-single,register-width = <32>; |
66 | pinctrl-single,function-mask = <0xffffffff>; | 66 | pinctrl-single,function-mask = <0xffffffff>; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | ocp { | 69 | ocp { |
70 | compatible = "simple-bus"; | 70 | compatible = "simple-bus"; |
71 | #address-cells = <1>; | 71 | #address-cells = <1>; |
72 | #size-cells = <1>; | 72 | #size-cells = <1>; |
73 | ranges; | 73 | ranges; |
74 | ti,hwmods = "l3_main"; | 74 | ti,hwmods = "l3_main"; |
75 | 75 | ||
76 | prcm: prcm@44df0000 { | 76 | prcm: prcm@44df0000 { |
77 | compatible = "ti,am4-prcm"; | 77 | compatible = "ti,am4-prcm"; |
78 | reg = <0x44df0000 0x11000>; | 78 | reg = <0x44df0000 0x11000>; |
79 | 79 | ||
80 | prcm_clocks: clocks { | 80 | prcm_clocks: clocks { |
81 | #address-cells = <1>; | 81 | #address-cells = <1>; |
82 | #size-cells = <0>; | 82 | #size-cells = <0>; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | prcm_clockdomains: clockdomains { | 85 | prcm_clockdomains: clockdomains { |
86 | }; | 86 | }; |
87 | }; | 87 | }; |
88 | 88 | ||
89 | scrm: scrm@44e10000 { | 89 | scrm: scrm@44e10000 { |
90 | compatible = "ti,am4-scrm"; | 90 | compatible = "ti,am4-scrm"; |
91 | reg = <0x44e10000 0x2000>; | 91 | reg = <0x44e10000 0x2000>; |
92 | 92 | ||
93 | scrm_clocks: clocks { | 93 | scrm_clocks: clocks { |
94 | #address-cells = <1>; | 94 | #address-cells = <1>; |
95 | #size-cells = <0>; | 95 | #size-cells = <0>; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | scrm_clockdomains: clockdomains { | 98 | scrm_clockdomains: clockdomains { |
99 | }; | 99 | }; |
100 | }; | 100 | }; |
101 | 101 | ||
102 | edma: edma@49000000 { | 102 | edma: edma@49000000 { |
103 | compatible = "ti,edma3"; | 103 | compatible = "ti,edma3"; |
104 | ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; | 104 | ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; |
105 | reg = <0x49000000 0x10000>, | 105 | reg = <0x49000000 0x10000>, |
106 | <0x44e10f90 0x10>; | 106 | <0x44e10f90 0x10>; |
107 | interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, | 107 | interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, |
108 | <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, | 108 | <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, |
109 | <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; | 109 | <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
110 | #dma-cells = <1>; | 110 | #dma-cells = <1>; |
111 | dma-channels = <64>; | 111 | dma-channels = <64>; |
112 | ti,edma-regions = <4>; | 112 | ti,edma-regions = <4>; |
113 | ti,edma-slots = <256>; | 113 | ti,edma-slots = <256>; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | uart0: serial@44e09000 { | 116 | uart0: serial@44e09000 { |
117 | compatible = "ti,am4372-uart","ti,omap2-uart"; | 117 | compatible = "ti,am4372-uart","ti,omap2-uart"; |
118 | reg = <0x44e09000 0x2000>; | 118 | reg = <0x44e09000 0x2000>; |
119 | interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; | 119 | interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; |
120 | ti,hwmods = "uart1"; | 120 | ti,hwmods = "uart1"; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | uart1: serial@48022000 { | 123 | uart1: serial@48022000 { |
124 | compatible = "ti,am4372-uart","ti,omap2-uart"; | 124 | compatible = "ti,am4372-uart","ti,omap2-uart"; |
125 | reg = <0x48022000 0x2000>; | 125 | reg = <0x48022000 0x2000>; |
126 | interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; | 126 | interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; |
127 | ti,hwmods = "uart2"; | 127 | ti,hwmods = "uart2"; |
128 | status = "disabled"; | 128 | status = "disabled"; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | uart2: serial@48024000 { | 131 | uart2: serial@48024000 { |
132 | compatible = "ti,am4372-uart","ti,omap2-uart"; | 132 | compatible = "ti,am4372-uart","ti,omap2-uart"; |
133 | reg = <0x48024000 0x2000>; | 133 | reg = <0x48024000 0x2000>; |
134 | interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; | 134 | interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; |
135 | ti,hwmods = "uart3"; | 135 | ti,hwmods = "uart3"; |
136 | status = "disabled"; | 136 | status = "disabled"; |
137 | }; | 137 | }; |
138 | 138 | ||
139 | uart3: serial@481a6000 { | 139 | uart3: serial@481a6000 { |
140 | compatible = "ti,am4372-uart","ti,omap2-uart"; | 140 | compatible = "ti,am4372-uart","ti,omap2-uart"; |
141 | reg = <0x481a6000 0x2000>; | 141 | reg = <0x481a6000 0x2000>; |
142 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; | 142 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; |
143 | ti,hwmods = "uart4"; | 143 | ti,hwmods = "uart4"; |
144 | status = "disabled"; | 144 | status = "disabled"; |
145 | }; | 145 | }; |
146 | 146 | ||
147 | uart4: serial@481a8000 { | 147 | uart4: serial@481a8000 { |
148 | compatible = "ti,am4372-uart","ti,omap2-uart"; | 148 | compatible = "ti,am4372-uart","ti,omap2-uart"; |
149 | reg = <0x481a8000 0x2000>; | 149 | reg = <0x481a8000 0x2000>; |
150 | interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; | 150 | interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; |
151 | ti,hwmods = "uart5"; | 151 | ti,hwmods = "uart5"; |
152 | status = "disabled"; | 152 | status = "disabled"; |
153 | }; | 153 | }; |
154 | 154 | ||
155 | uart5: serial@481aa000 { | 155 | uart5: serial@481aa000 { |
156 | compatible = "ti,am4372-uart","ti,omap2-uart"; | 156 | compatible = "ti,am4372-uart","ti,omap2-uart"; |
157 | reg = <0x481aa000 0x2000>; | 157 | reg = <0x481aa000 0x2000>; |
158 | interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; | 158 | interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; |
159 | ti,hwmods = "uart6"; | 159 | ti,hwmods = "uart6"; |
160 | status = "disabled"; | 160 | status = "disabled"; |
161 | }; | 161 | }; |
162 | 162 | ||
163 | mailbox: mailbox@480C8000 { | 163 | mailbox: mailbox@480C8000 { |
164 | compatible = "ti,omap4-mailbox"; | 164 | compatible = "ti,omap4-mailbox"; |
165 | reg = <0x480C8000 0x200>; | 165 | reg = <0x480C8000 0x200>; |
166 | interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; | 166 | interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; |
167 | ti,hwmods = "mailbox"; | 167 | ti,hwmods = "mailbox"; |
168 | ti,mbox-num-users = <4>; | 168 | ti,mbox-num-users = <4>; |
169 | ti,mbox-num-fifos = <8>; | 169 | ti,mbox-num-fifos = <8>; |
170 | ti,mbox-names = "wkup_m3"; | 170 | ti,mbox-names = "wkup_m3"; |
171 | ti,mbox-data = <0 0 0 0>; | 171 | ti,mbox-data = <0 0 0 0>; |
172 | status = "disabled"; | 172 | status = "disabled"; |
173 | }; | 173 | }; |
174 | 174 | ||
175 | timer1: timer@44e31000 { | 175 | timer1: timer@44e31000 { |
176 | compatible = "ti,am4372-timer-1ms","ti,am335x-timer-1ms"; | 176 | compatible = "ti,am4372-timer-1ms","ti,am335x-timer-1ms"; |
177 | reg = <0x44e31000 0x400>; | 177 | reg = <0x44e31000 0x400>; |
178 | interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; | 178 | interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; |
179 | ti,timer-alwon; | 179 | ti,timer-alwon; |
180 | ti,hwmods = "timer1"; | 180 | ti,hwmods = "timer1"; |
181 | }; | 181 | }; |
182 | 182 | ||
183 | timer2: timer@48040000 { | 183 | timer2: timer@48040000 { |
184 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 184 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
185 | reg = <0x48040000 0x400>; | 185 | reg = <0x48040000 0x400>; |
186 | interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; | 186 | interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; |
187 | ti,hwmods = "timer2"; | 187 | ti,hwmods = "timer2"; |
188 | }; | 188 | }; |
189 | 189 | ||
190 | timer3: timer@48042000 { | 190 | timer3: timer@48042000 { |
191 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 191 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
192 | reg = <0x48042000 0x400>; | 192 | reg = <0x48042000 0x400>; |
193 | interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; | 193 | interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; |
194 | ti,hwmods = "timer3"; | 194 | ti,hwmods = "timer3"; |
195 | status = "disabled"; | 195 | status = "disabled"; |
196 | }; | 196 | }; |
197 | 197 | ||
198 | timer4: timer@48044000 { | 198 | timer4: timer@48044000 { |
199 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 199 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
200 | reg = <0x48044000 0x400>; | 200 | reg = <0x48044000 0x400>; |
201 | interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; | 201 | interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; |
202 | ti,timer-pwm; | 202 | ti,timer-pwm; |
203 | ti,hwmods = "timer4"; | 203 | ti,hwmods = "timer4"; |
204 | status = "disabled"; | 204 | status = "disabled"; |
205 | }; | 205 | }; |
206 | 206 | ||
207 | timer5: timer@48046000 { | 207 | timer5: timer@48046000 { |
208 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 208 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
209 | reg = <0x48046000 0x400>; | 209 | reg = <0x48046000 0x400>; |
210 | interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; | 210 | interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; |
211 | ti,timer-pwm; | 211 | ti,timer-pwm; |
212 | ti,hwmods = "timer5"; | 212 | ti,hwmods = "timer5"; |
213 | status = "disabled"; | 213 | status = "disabled"; |
214 | }; | 214 | }; |
215 | 215 | ||
216 | timer6: timer@48048000 { | 216 | timer6: timer@48048000 { |
217 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 217 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
218 | reg = <0x48048000 0x400>; | 218 | reg = <0x48048000 0x400>; |
219 | interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; | 219 | interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; |
220 | ti,timer-pwm; | 220 | ti,timer-pwm; |
221 | ti,hwmods = "timer6"; | 221 | ti,hwmods = "timer6"; |
222 | status = "disabled"; | 222 | status = "disabled"; |
223 | }; | 223 | }; |
224 | 224 | ||
225 | timer7: timer@4804a000 { | 225 | timer7: timer@4804a000 { |
226 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 226 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
227 | reg = <0x4804a000 0x400>; | 227 | reg = <0x4804a000 0x400>; |
228 | interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; | 228 | interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; |
229 | ti,timer-pwm; | 229 | ti,timer-pwm; |
230 | ti,hwmods = "timer7"; | 230 | ti,hwmods = "timer7"; |
231 | status = "disabled"; | 231 | status = "disabled"; |
232 | }; | 232 | }; |
233 | 233 | ||
234 | timer8: timer@481c1000 { | 234 | timer8: timer@481c1000 { |
235 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 235 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
236 | reg = <0x481c1000 0x400>; | 236 | reg = <0x481c1000 0x400>; |
237 | interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; | 237 | interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; |
238 | ti,hwmods = "timer8"; | 238 | ti,hwmods = "timer8"; |
239 | status = "disabled"; | 239 | status = "disabled"; |
240 | }; | 240 | }; |
241 | 241 | ||
242 | timer9: timer@4833d000 { | 242 | timer9: timer@4833d000 { |
243 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 243 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
244 | reg = <0x4833d000 0x400>; | 244 | reg = <0x4833d000 0x400>; |
245 | interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; | 245 | interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; |
246 | ti,hwmods = "timer9"; | 246 | ti,hwmods = "timer9"; |
247 | status = "disabled"; | 247 | status = "disabled"; |
248 | }; | 248 | }; |
249 | 249 | ||
250 | timer10: timer@4833f000 { | 250 | timer10: timer@4833f000 { |
251 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 251 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
252 | reg = <0x4833f000 0x400>; | 252 | reg = <0x4833f000 0x400>; |
253 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; | 253 | interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; |
254 | ti,hwmods = "timer10"; | 254 | ti,hwmods = "timer10"; |
255 | status = "disabled"; | 255 | status = "disabled"; |
256 | }; | 256 | }; |
257 | 257 | ||
258 | timer11: timer@48341000 { | 258 | timer11: timer@48341000 { |
259 | compatible = "ti,am4372-timer","ti,am335x-timer"; | 259 | compatible = "ti,am4372-timer","ti,am335x-timer"; |
260 | reg = <0x48341000 0x400>; | 260 | reg = <0x48341000 0x400>; |
261 | interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; | 261 | interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; |
262 | ti,hwmods = "timer11"; | 262 | ti,hwmods = "timer11"; |
263 | status = "disabled"; | 263 | status = "disabled"; |
264 | }; | 264 | }; |
265 | 265 | ||
266 | counter32k: counter@44e86000 { | 266 | counter32k: counter@44e86000 { |
267 | compatible = "ti,am4372-counter32k","ti,omap-counter32k"; | 267 | compatible = "ti,am4372-counter32k","ti,omap-counter32k"; |
268 | reg = <0x44e86000 0x40>; | 268 | reg = <0x44e86000 0x40>; |
269 | ti,hwmods = "counter_32k"; | 269 | ti,hwmods = "counter_32k"; |
270 | }; | 270 | }; |
271 | 271 | ||
272 | rtc@44e3e000 { | 272 | rtc@44e3e000 { |
273 | compatible = "ti,am4372-rtc","ti,da830-rtc"; | 273 | compatible = "ti,am4372-rtc","ti,da830-rtc"; |
274 | reg = <0x44e3e000 0x1000>; | 274 | reg = <0x44e3e000 0x1000>; |
275 | interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH | 275 | interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH |
276 | GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; | 276 | GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; |
277 | ti,hwmods = "rtc"; | 277 | ti,hwmods = "rtc"; |
278 | status = "disabled"; | 278 | status = "disabled"; |
279 | }; | 279 | }; |
280 | 280 | ||
281 | wdt@44e35000 { | 281 | wdt@44e35000 { |
282 | compatible = "ti,am4372-wdt","ti,omap3-wdt"; | 282 | compatible = "ti,am4372-wdt","ti,omap3-wdt"; |
283 | reg = <0x44e35000 0x1000>; | 283 | reg = <0x44e35000 0x1000>; |
284 | interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; | 284 | interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; |
285 | ti,hwmods = "wd_timer2"; | 285 | ti,hwmods = "wd_timer2"; |
286 | }; | 286 | }; |
287 | 287 | ||
288 | gpio0: gpio@44e07000 { | 288 | gpio0: gpio@44e07000 { |
289 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; | 289 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; |
290 | reg = <0x44e07000 0x1000>; | 290 | reg = <0x44e07000 0x1000>; |
291 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; | 291 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; |
292 | gpio-controller; | 292 | gpio-controller; |
293 | #gpio-cells = <2>; | 293 | #gpio-cells = <2>; |
294 | interrupt-controller; | 294 | interrupt-controller; |
295 | #interrupt-cells = <2>; | 295 | #interrupt-cells = <2>; |
296 | ti,hwmods = "gpio1"; | 296 | ti,hwmods = "gpio1"; |
297 | status = "disabled"; | 297 | status = "disabled"; |
298 | }; | 298 | }; |
299 | 299 | ||
300 | gpio1: gpio@4804c000 { | 300 | gpio1: gpio@4804c000 { |
301 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; | 301 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; |
302 | reg = <0x4804c000 0x1000>; | 302 | reg = <0x4804c000 0x1000>; |
303 | interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | 303 | interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; |
304 | gpio-controller; | 304 | gpio-controller; |
305 | #gpio-cells = <2>; | 305 | #gpio-cells = <2>; |
306 | interrupt-controller; | 306 | interrupt-controller; |
307 | #interrupt-cells = <2>; | 307 | #interrupt-cells = <2>; |
308 | ti,hwmods = "gpio2"; | 308 | ti,hwmods = "gpio2"; |
309 | status = "disabled"; | 309 | status = "disabled"; |
310 | }; | 310 | }; |
311 | 311 | ||
312 | gpio2: gpio@481ac000 { | 312 | gpio2: gpio@481ac000 { |
313 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; | 313 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; |
314 | reg = <0x481ac000 0x1000>; | 314 | reg = <0x481ac000 0x1000>; |
315 | interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; | 315 | interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; |
316 | gpio-controller; | 316 | gpio-controller; |
317 | #gpio-cells = <2>; | 317 | #gpio-cells = <2>; |
318 | interrupt-controller; | 318 | interrupt-controller; |
319 | #interrupt-cells = <2>; | 319 | #interrupt-cells = <2>; |
320 | ti,hwmods = "gpio3"; | 320 | ti,hwmods = "gpio3"; |
321 | status = "disabled"; | 321 | status = "disabled"; |
322 | }; | 322 | }; |
323 | 323 | ||
324 | gpio3: gpio@481ae000 { | 324 | gpio3: gpio@481ae000 { |
325 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; | 325 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; |
326 | reg = <0x481ae000 0x1000>; | 326 | reg = <0x481ae000 0x1000>; |
327 | interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; | 327 | interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; |
328 | gpio-controller; | 328 | gpio-controller; |
329 | #gpio-cells = <2>; | 329 | #gpio-cells = <2>; |
330 | interrupt-controller; | 330 | interrupt-controller; |
331 | #interrupt-cells = <2>; | 331 | #interrupt-cells = <2>; |
332 | ti,hwmods = "gpio4"; | 332 | ti,hwmods = "gpio4"; |
333 | status = "disabled"; | 333 | status = "disabled"; |
334 | }; | 334 | }; |
335 | 335 | ||
336 | gpio4: gpio@48320000 { | 336 | gpio4: gpio@48320000 { |
337 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; | 337 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; |
338 | reg = <0x48320000 0x1000>; | 338 | reg = <0x48320000 0x1000>; |
339 | interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; | 339 | interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; |
340 | gpio-controller; | 340 | gpio-controller; |
341 | #gpio-cells = <2>; | 341 | #gpio-cells = <2>; |
342 | interrupt-controller; | 342 | interrupt-controller; |
343 | #interrupt-cells = <2>; | 343 | #interrupt-cells = <2>; |
344 | ti,hwmods = "gpio5"; | 344 | ti,hwmods = "gpio5"; |
345 | status = "disabled"; | 345 | status = "disabled"; |
346 | }; | 346 | }; |
347 | 347 | ||
348 | gpio5: gpio@48322000 { | 348 | gpio5: gpio@48322000 { |
349 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; | 349 | compatible = "ti,am4372-gpio","ti,omap4-gpio"; |
350 | reg = <0x48322000 0x1000>; | 350 | reg = <0x48322000 0x1000>; |
351 | interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; | 351 | interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; |
352 | gpio-controller; | 352 | gpio-controller; |
353 | #gpio-cells = <2>; | 353 | #gpio-cells = <2>; |
354 | interrupt-controller; | 354 | interrupt-controller; |
355 | #interrupt-cells = <2>; | 355 | #interrupt-cells = <2>; |
356 | ti,hwmods = "gpio6"; | 356 | ti,hwmods = "gpio6"; |
357 | status = "disabled"; | 357 | status = "disabled"; |
358 | }; | 358 | }; |
359 | 359 | ||
360 | hwspinlock: spinlock@480ca000 { | 360 | hwspinlock: spinlock@480ca000 { |
361 | compatible = "ti,omap4-hwspinlock"; | 361 | compatible = "ti,omap4-hwspinlock"; |
362 | reg = <0x480ca000 0x1000>; | 362 | reg = <0x480ca000 0x1000>; |
363 | ti,hwmods = "spinlock"; | 363 | ti,hwmods = "spinlock"; |
364 | #hwlock-cells = <1>; | 364 | #hwlock-cells = <1>; |
365 | }; | 365 | }; |
366 | 366 | ||
367 | i2c0: i2c@44e0b000 { | 367 | i2c0: i2c@44e0b000 { |
368 | compatible = "ti,am4372-i2c","ti,omap4-i2c"; | 368 | compatible = "ti,am4372-i2c","ti,omap4-i2c"; |
369 | reg = <0x44e0b000 0x1000>; | 369 | reg = <0x44e0b000 0x1000>; |
370 | interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; | 370 | interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; |
371 | ti,hwmods = "i2c1"; | 371 | ti,hwmods = "i2c1"; |
372 | #address-cells = <1>; | 372 | #address-cells = <1>; |
373 | #size-cells = <0>; | 373 | #size-cells = <0>; |
374 | status = "disabled"; | 374 | status = "disabled"; |
375 | }; | 375 | }; |
376 | 376 | ||
377 | i2c1: i2c@4802a000 { | 377 | i2c1: i2c@4802a000 { |
378 | compatible = "ti,am4372-i2c","ti,omap4-i2c"; | 378 | compatible = "ti,am4372-i2c","ti,omap4-i2c"; |
379 | reg = <0x4802a000 0x1000>; | 379 | reg = <0x4802a000 0x1000>; |
380 | interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; | 380 | interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; |
381 | ti,hwmods = "i2c2"; | 381 | ti,hwmods = "i2c2"; |
382 | #address-cells = <1>; | 382 | #address-cells = <1>; |
383 | #size-cells = <0>; | 383 | #size-cells = <0>; |
384 | status = "disabled"; | 384 | status = "disabled"; |
385 | }; | 385 | }; |
386 | 386 | ||
387 | i2c2: i2c@4819c000 { | 387 | i2c2: i2c@4819c000 { |
388 | compatible = "ti,am4372-i2c","ti,omap4-i2c"; | 388 | compatible = "ti,am4372-i2c","ti,omap4-i2c"; |
389 | reg = <0x4819c000 0x1000>; | 389 | reg = <0x4819c000 0x1000>; |
390 | interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; | 390 | interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; |
391 | ti,hwmods = "i2c3"; | 391 | ti,hwmods = "i2c3"; |
392 | #address-cells = <1>; | 392 | #address-cells = <1>; |
393 | #size-cells = <0>; | 393 | #size-cells = <0>; |
394 | status = "disabled"; | 394 | status = "disabled"; |
395 | }; | 395 | }; |
396 | 396 | ||
397 | spi0: spi@48030000 { | 397 | spi0: spi@48030000 { |
398 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; | 398 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; |
399 | reg = <0x48030000 0x400>; | 399 | reg = <0x48030000 0x400>; |
400 | interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; | 400 | interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; |
401 | ti,hwmods = "spi0"; | 401 | ti,hwmods = "spi0"; |
402 | #address-cells = <1>; | 402 | #address-cells = <1>; |
403 | #size-cells = <0>; | 403 | #size-cells = <0>; |
404 | status = "disabled"; | 404 | status = "disabled"; |
405 | }; | 405 | }; |
406 | 406 | ||
407 | mmc1: mmc@48060000 { | 407 | mmc1: mmc@48060000 { |
408 | compatible = "ti,omap4-hsmmc"; | 408 | compatible = "ti,omap4-hsmmc"; |
409 | reg = <0x48060000 0x1000>; | 409 | reg = <0x48060000 0x1000>; |
410 | ti,hwmods = "mmc1"; | 410 | ti,hwmods = "mmc1"; |
411 | ti,dual-volt; | 411 | ti,dual-volt; |
412 | ti,needs-special-reset; | 412 | ti,needs-special-reset; |
413 | dmas = <&edma 24 | 413 | dmas = <&edma 24 |
414 | &edma 25>; | 414 | &edma 25>; |
415 | dma-names = "tx", "rx"; | 415 | dma-names = "tx", "rx"; |
416 | interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; | 416 | interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; |
417 | status = "disabled"; | 417 | status = "disabled"; |
418 | }; | 418 | }; |
419 | 419 | ||
420 | mmc2: mmc@481d8000 { | 420 | mmc2: mmc@481d8000 { |
421 | compatible = "ti,omap4-hsmmc"; | 421 | compatible = "ti,omap4-hsmmc"; |
422 | reg = <0x481d8000 0x1000>; | 422 | reg = <0x481d8000 0x1000>; |
423 | ti,hwmods = "mmc2"; | 423 | ti,hwmods = "mmc2"; |
424 | ti,needs-special-reset; | 424 | ti,needs-special-reset; |
425 | dmas = <&edma 2 | 425 | dmas = <&edma 2 |
426 | &edma 3>; | 426 | &edma 3>; |
427 | dma-names = "tx", "rx"; | 427 | dma-names = "tx", "rx"; |
428 | interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; | 428 | interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; |
429 | status = "disabled"; | 429 | status = "disabled"; |
430 | }; | 430 | }; |
431 | 431 | ||
432 | mmc3: mmc@47810000 { | 432 | mmc3: mmc@47810000 { |
433 | compatible = "ti,omap4-hsmmc"; | 433 | compatible = "ti,omap4-hsmmc"; |
434 | reg = <0x47810000 0x1000>; | 434 | reg = <0x47810000 0x1000>; |
435 | ti,hwmods = "mmc3"; | 435 | ti,hwmods = "mmc3"; |
436 | ti,needs-special-reset; | 436 | ti,needs-special-reset; |
437 | interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; | 437 | interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; |
438 | status = "disabled"; | 438 | status = "disabled"; |
439 | }; | 439 | }; |
440 | 440 | ||
441 | spi1: spi@481a0000 { | 441 | spi1: spi@481a0000 { |
442 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; | 442 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; |
443 | reg = <0x481a0000 0x400>; | 443 | reg = <0x481a0000 0x400>; |
444 | interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; | 444 | interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; |
445 | ti,hwmods = "spi1"; | 445 | ti,hwmods = "spi1"; |
446 | #address-cells = <1>; | 446 | #address-cells = <1>; |
447 | #size-cells = <0>; | 447 | #size-cells = <0>; |
448 | status = "disabled"; | 448 | status = "disabled"; |
449 | }; | 449 | }; |
450 | 450 | ||
451 | spi2: spi@481a2000 { | 451 | spi2: spi@481a2000 { |
452 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; | 452 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; |
453 | reg = <0x481a2000 0x400>; | 453 | reg = <0x481a2000 0x400>; |
454 | interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; | 454 | interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; |
455 | ti,hwmods = "spi2"; | 455 | ti,hwmods = "spi2"; |
456 | #address-cells = <1>; | 456 | #address-cells = <1>; |
457 | #size-cells = <0>; | 457 | #size-cells = <0>; |
458 | status = "disabled"; | 458 | status = "disabled"; |
459 | }; | 459 | }; |
460 | 460 | ||
461 | spi3: spi@481a4000 { | 461 | spi3: spi@481a4000 { |
462 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; | 462 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; |
463 | reg = <0x481a4000 0x400>; | 463 | reg = <0x481a4000 0x400>; |
464 | interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; | 464 | interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; |
465 | ti,hwmods = "spi3"; | 465 | ti,hwmods = "spi3"; |
466 | #address-cells = <1>; | 466 | #address-cells = <1>; |
467 | #size-cells = <0>; | 467 | #size-cells = <0>; |
468 | status = "disabled"; | 468 | status = "disabled"; |
469 | }; | 469 | }; |
470 | 470 | ||
471 | spi4: spi@48345000 { | 471 | spi4: spi@48345000 { |
472 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; | 472 | compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; |
473 | reg = <0x48345000 0x400>; | 473 | reg = <0x48345000 0x400>; |
474 | interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; | 474 | interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; |
475 | ti,hwmods = "spi4"; | 475 | ti,hwmods = "spi4"; |
476 | #address-cells = <1>; | 476 | #address-cells = <1>; |
477 | #size-cells = <0>; | 477 | #size-cells = <0>; |
478 | status = "disabled"; | 478 | status = "disabled"; |
479 | }; | 479 | }; |
480 | 480 | ||
481 | mac: ethernet@4a100000 { | 481 | mac: ethernet@4a100000 { |
482 | compatible = "ti,am4372-cpsw","ti,cpsw"; | 482 | compatible = "ti,am4372-cpsw","ti,cpsw"; |
483 | reg = <0x4a100000 0x800 | 483 | reg = <0x4a100000 0x800 |
484 | 0x4a101200 0x100>; | 484 | 0x4a101200 0x100>; |
485 | interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH | 485 | interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH |
486 | GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH | 486 | GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH |
487 | GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH | 487 | GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH |
488 | GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; | 488 | GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; |
489 | #address-cells = <1>; | 489 | #address-cells = <1>; |
490 | #size-cells = <1>; | 490 | #size-cells = <1>; |
491 | ti,hwmods = "cpgmac0"; | 491 | ti,hwmods = "cpgmac0"; |
492 | status = "disabled"; | 492 | status = "disabled"; |
493 | cpdma_channels = <8>; | 493 | cpdma_channels = <8>; |
494 | ale_entries = <1024>; | 494 | ale_entries = <1024>; |
495 | bd_ram_size = <0x2000>; | 495 | bd_ram_size = <0x2000>; |
496 | no_bd_ram = <0>; | 496 | no_bd_ram = <0>; |
497 | rx_descs = <64>; | 497 | rx_descs = <64>; |
498 | mac_control = <0x20>; | 498 | mac_control = <0x20>; |
499 | slaves = <2>; | 499 | slaves = <2>; |
500 | active_slave = <0>; | 500 | active_slave = <0>; |
501 | cpts_clock_mult = <0x80000000>; | 501 | cpts_clock_mult = <0x80000000>; |
502 | cpts_clock_shift = <29>; | 502 | cpts_clock_shift = <29>; |
503 | ranges; | 503 | ranges; |
504 | 504 | ||
505 | davinci_mdio: mdio@4a101000 { | 505 | davinci_mdio: mdio@4a101000 { |
506 | compatible = "ti,am4372-mdio","ti,davinci_mdio"; | 506 | compatible = "ti,am4372-mdio","ti,davinci_mdio"; |
507 | reg = <0x4a101000 0x100>; | 507 | reg = <0x4a101000 0x100>; |
508 | #address-cells = <1>; | 508 | #address-cells = <1>; |
509 | #size-cells = <0>; | 509 | #size-cells = <0>; |
510 | ti,hwmods = "davinci_mdio"; | 510 | ti,hwmods = "davinci_mdio"; |
511 | bus_freq = <1000000>; | 511 | bus_freq = <1000000>; |
512 | status = "disabled"; | 512 | status = "disabled"; |
513 | }; | 513 | }; |
514 | 514 | ||
515 | cpsw_emac0: slave@4a100200 { | 515 | cpsw_emac0: slave@4a100200 { |
516 | /* Filled in by U-Boot */ | 516 | /* Filled in by U-Boot */ |
517 | mac-address = [ 00 00 00 00 00 00 ]; | 517 | mac-address = [ 00 00 00 00 00 00 ]; |
518 | }; | 518 | }; |
519 | 519 | ||
520 | cpsw_emac1: slave@4a100300 { | 520 | cpsw_emac1: slave@4a100300 { |
521 | /* Filled in by U-Boot */ | 521 | /* Filled in by U-Boot */ |
522 | mac-address = [ 00 00 00 00 00 00 ]; | 522 | mac-address = [ 00 00 00 00 00 00 ]; |
523 | }; | 523 | }; |
524 | }; | 524 | }; |
525 | 525 | ||
526 | epwmss0: epwmss@48300000 { | 526 | epwmss0: epwmss@48300000 { |
527 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; | 527 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; |
528 | reg = <0x48300000 0x10>; | 528 | reg = <0x48300000 0x10>; |
529 | #address-cells = <1>; | 529 | #address-cells = <1>; |
530 | #size-cells = <1>; | 530 | #size-cells = <1>; |
531 | ranges; | 531 | ranges; |
532 | ti,hwmods = "epwmss0"; | 532 | ti,hwmods = "epwmss0"; |
533 | status = "disabled"; | 533 | status = "disabled"; |
534 | 534 | ||
535 | ecap0: ecap@48300100 { | 535 | ecap0: ecap@48300100 { |
536 | compatible = "ti,am4372-ecap","ti,am33xx-ecap"; | 536 | compatible = "ti,am4372-ecap","ti,am33xx-ecap"; |
537 | #pwm-cells = <3>; | 537 | #pwm-cells = <3>; |
538 | reg = <0x48300100 0x80>; | 538 | reg = <0x48300100 0x80>; |
539 | ti,hwmods = "ecap0"; | 539 | ti,hwmods = "ecap0"; |
540 | status = "disabled"; | 540 | status = "disabled"; |
541 | }; | 541 | }; |
542 | 542 | ||
543 | ehrpwm0: ehrpwm@48300200 { | 543 | ehrpwm0: ehrpwm@48300200 { |
544 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; | 544 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; |
545 | #pwm-cells = <3>; | 545 | #pwm-cells = <3>; |
546 | reg = <0x48300200 0x80>; | 546 | reg = <0x48300200 0x80>; |
547 | ti,hwmods = "ehrpwm0"; | 547 | ti,hwmods = "ehrpwm0"; |
548 | status = "disabled"; | 548 | status = "disabled"; |
549 | }; | 549 | }; |
550 | }; | 550 | }; |
551 | 551 | ||
552 | epwmss1: epwmss@48302000 { | 552 | epwmss1: epwmss@48302000 { |
553 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; | 553 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; |
554 | reg = <0x48302000 0x10>; | 554 | reg = <0x48302000 0x10>; |
555 | #address-cells = <1>; | 555 | #address-cells = <1>; |
556 | #size-cells = <1>; | 556 | #size-cells = <1>; |
557 | ranges; | 557 | ranges; |
558 | ti,hwmods = "epwmss1"; | 558 | ti,hwmods = "epwmss1"; |
559 | status = "disabled"; | 559 | status = "disabled"; |
560 | 560 | ||
561 | ecap1: ecap@48302100 { | 561 | ecap1: ecap@48302100 { |
562 | compatible = "ti,am4372-ecap","ti,am33xx-ecap"; | 562 | compatible = "ti,am4372-ecap","ti,am33xx-ecap"; |
563 | #pwm-cells = <3>; | 563 | #pwm-cells = <3>; |
564 | reg = <0x48302100 0x80>; | 564 | reg = <0x48302100 0x80>; |
565 | ti,hwmods = "ecap1"; | 565 | ti,hwmods = "ecap1"; |
566 | status = "disabled"; | 566 | status = "disabled"; |
567 | }; | 567 | }; |
568 | 568 | ||
569 | ehrpwm1: ehrpwm@48302200 { | 569 | ehrpwm1: ehrpwm@48302200 { |
570 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; | 570 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; |
571 | #pwm-cells = <3>; | 571 | #pwm-cells = <3>; |
572 | reg = <0x48302200 0x80>; | 572 | reg = <0x48302200 0x80>; |
573 | ti,hwmods = "ehrpwm1"; | 573 | ti,hwmods = "ehrpwm1"; |
574 | status = "disabled"; | 574 | status = "disabled"; |
575 | }; | 575 | }; |
576 | }; | 576 | }; |
577 | 577 | ||
578 | epwmss2: epwmss@48304000 { | 578 | epwmss2: epwmss@48304000 { |
579 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; | 579 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; |
580 | reg = <0x48304000 0x10>; | 580 | reg = <0x48304000 0x10>; |
581 | #address-cells = <1>; | 581 | #address-cells = <1>; |
582 | #size-cells = <1>; | 582 | #size-cells = <1>; |
583 | ranges; | 583 | ranges; |
584 | ti,hwmods = "epwmss2"; | 584 | ti,hwmods = "epwmss2"; |
585 | status = "disabled"; | 585 | status = "disabled"; |
586 | 586 | ||
587 | ecap2: ecap@48304100 { | 587 | ecap2: ecap@48304100 { |
588 | compatible = "ti,am4372-ecap","ti,am33xx-ecap"; | 588 | compatible = "ti,am4372-ecap","ti,am33xx-ecap"; |
589 | #pwm-cells = <3>; | 589 | #pwm-cells = <3>; |
590 | reg = <0x48304100 0x80>; | 590 | reg = <0x48304100 0x80>; |
591 | ti,hwmods = "ecap2"; | 591 | ti,hwmods = "ecap2"; |
592 | status = "disabled"; | 592 | status = "disabled"; |
593 | }; | 593 | }; |
594 | 594 | ||
595 | ehrpwm2: ehrpwm@48304200 { | 595 | ehrpwm2: ehrpwm@48304200 { |
596 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; | 596 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; |
597 | #pwm-cells = <3>; | 597 | #pwm-cells = <3>; |
598 | reg = <0x48304200 0x80>; | 598 | reg = <0x48304200 0x80>; |
599 | ti,hwmods = "ehrpwm2"; | 599 | ti,hwmods = "ehrpwm2"; |
600 | status = "disabled"; | 600 | status = "disabled"; |
601 | }; | 601 | }; |
602 | }; | 602 | }; |
603 | 603 | ||
604 | epwmss3: epwmss@48306000 { | 604 | epwmss3: epwmss@48306000 { |
605 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; | 605 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; |
606 | reg = <0x48306000 0x10>; | 606 | reg = <0x48306000 0x10>; |
607 | #address-cells = <1>; | 607 | #address-cells = <1>; |
608 | #size-cells = <1>; | 608 | #size-cells = <1>; |
609 | ranges; | 609 | ranges; |
610 | ti,hwmods = "epwmss3"; | 610 | ti,hwmods = "epwmss3"; |
611 | status = "disabled"; | 611 | status = "disabled"; |
612 | 612 | ||
613 | ehrpwm3: ehrpwm@48306200 { | 613 | ehrpwm3: ehrpwm@48306200 { |
614 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; | 614 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; |
615 | #pwm-cells = <3>; | 615 | #pwm-cells = <3>; |
616 | reg = <0x48306200 0x80>; | 616 | reg = <0x48306200 0x80>; |
617 | ti,hwmods = "ehrpwm3"; | 617 | ti,hwmods = "ehrpwm3"; |
618 | status = "disabled"; | 618 | status = "disabled"; |
619 | }; | 619 | }; |
620 | }; | 620 | }; |
621 | 621 | ||
622 | epwmss4: epwmss@48308000 { | 622 | epwmss4: epwmss@48308000 { |
623 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; | 623 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; |
624 | reg = <0x48308000 0x10>; | 624 | reg = <0x48308000 0x10>; |
625 | #address-cells = <1>; | 625 | #address-cells = <1>; |
626 | #size-cells = <1>; | 626 | #size-cells = <1>; |
627 | ranges; | 627 | ranges; |
628 | ti,hwmods = "epwmss4"; | 628 | ti,hwmods = "epwmss4"; |
629 | status = "disabled"; | 629 | status = "disabled"; |
630 | 630 | ||
631 | ehrpwm4: ehrpwm@48308200 { | 631 | ehrpwm4: ehrpwm@48308200 { |
632 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; | 632 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; |
633 | #pwm-cells = <3>; | 633 | #pwm-cells = <3>; |
634 | reg = <0x48308200 0x80>; | 634 | reg = <0x48308200 0x80>; |
635 | ti,hwmods = "ehrpwm4"; | 635 | ti,hwmods = "ehrpwm4"; |
636 | status = "disabled"; | 636 | status = "disabled"; |
637 | }; | 637 | }; |
638 | }; | 638 | }; |
639 | 639 | ||
640 | epwmss5: epwmss@4830a000 { | 640 | epwmss5: epwmss@4830a000 { |
641 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; | 641 | compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; |
642 | reg = <0x4830a000 0x10>; | 642 | reg = <0x4830a000 0x10>; |
643 | #address-cells = <1>; | 643 | #address-cells = <1>; |
644 | #size-cells = <1>; | 644 | #size-cells = <1>; |
645 | ranges; | 645 | ranges; |
646 | ti,hwmods = "epwmss5"; | 646 | ti,hwmods = "epwmss5"; |
647 | status = "disabled"; | 647 | status = "disabled"; |
648 | 648 | ||
649 | ehrpwm5: ehrpwm@4830a200 { | 649 | ehrpwm5: ehrpwm@4830a200 { |
650 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; | 650 | compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; |
651 | #pwm-cells = <3>; | 651 | #pwm-cells = <3>; |
652 | reg = <0x4830a200 0x80>; | 652 | reg = <0x4830a200 0x80>; |
653 | ti,hwmods = "ehrpwm5"; | 653 | ti,hwmods = "ehrpwm5"; |
654 | status = "disabled"; | 654 | status = "disabled"; |
655 | }; | 655 | }; |
656 | }; | 656 | }; |
657 | 657 | ||
658 | sham: sham@53100000 { | 658 | sham: sham@53100000 { |
659 | compatible = "ti,omap5-sham"; | 659 | compatible = "ti,omap5-sham"; |
660 | ti,hwmods = "sham"; | 660 | ti,hwmods = "sham"; |
661 | reg = <0x53100000 0x300>; | 661 | reg = <0x53100000 0x300>; |
662 | dmas = <&edma 36>; | 662 | dmas = <&edma 36>; |
663 | dma-names = "rx"; | 663 | dma-names = "rx"; |
664 | interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; | 664 | interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; |
665 | }; | 665 | }; |
666 | 666 | ||
667 | aes: aes@53501000 { | 667 | aes: aes@53501000 { |
668 | compatible = "ti,omap4-aes"; | 668 | compatible = "ti,omap4-aes"; |
669 | ti,hwmods = "aes"; | 669 | ti,hwmods = "aes"; |
670 | reg = <0x53501000 0xa0>; | 670 | reg = <0x53501000 0xa0>; |
671 | interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; | 671 | interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; |
672 | dmas = <&edma 6 | 672 | dmas = <&edma 6 |
673 | &edma 5>; | 673 | &edma 5>; |
674 | dma-names = "tx", "rx"; | 674 | dma-names = "tx", "rx"; |
675 | }; | 675 | }; |
676 | 676 | ||
677 | des: des@53701000 { | 677 | des: des@53701000 { |
678 | compatible = "ti,omap4-des"; | 678 | compatible = "ti,omap4-des"; |
679 | ti,hwmods = "des"; | 679 | ti,hwmods = "des"; |
680 | reg = <0x53701000 0xa0>; | 680 | reg = <0x53701000 0xa0>; |
681 | interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>; | 681 | interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>; |
682 | dmas = <&edma 34 | 682 | dmas = <&edma 34 |
683 | &edma 33>; | 683 | &edma 33>; |
684 | dma-names = "tx", "rx"; | 684 | dma-names = "tx", "rx"; |
685 | }; | 685 | }; |
686 | 686 | ||
687 | mcasp0: mcasp@48038000 { | 687 | mcasp0: mcasp@48038000 { |
688 | compatible = "ti,am33xx-mcasp-audio"; | 688 | compatible = "ti,am33xx-mcasp-audio"; |
689 | ti,hwmods = "mcasp0"; | 689 | ti,hwmods = "mcasp0"; |
690 | reg = <0x48038000 0x2000>, | 690 | reg = <0x48038000 0x2000>, |
691 | <0x46000000 0x400000>; | 691 | <0x46000000 0x400000>; |
692 | reg-names = "mpu", "dat"; | 692 | reg-names = "mpu", "dat"; |
693 | interrupts = <80>, <81>; | 693 | interrupts = <80>, <81>; |
694 | interrupts-names = "tx", "rx"; | 694 | interrupt-names = "tx", "rx"; |
695 | status = "disabled"; | 695 | status = "disabled"; |
696 | dmas = <&edma 8>, | 696 | dmas = <&edma 8>, |
697 | <&edma 9>; | 697 | <&edma 9>; |
698 | dma-names = "tx", "rx"; | 698 | dma-names = "tx", "rx"; |
699 | }; | 699 | }; |
700 | 700 | ||
701 | mcasp1: mcasp@4803C000 { | 701 | mcasp1: mcasp@4803C000 { |
702 | compatible = "ti,am33xx-mcasp-audio"; | 702 | compatible = "ti,am33xx-mcasp-audio"; |
703 | ti,hwmods = "mcasp1"; | 703 | ti,hwmods = "mcasp1"; |
704 | reg = <0x4803C000 0x2000>, | 704 | reg = <0x4803C000 0x2000>, |
705 | <0x46400000 0x400000>; | 705 | <0x46400000 0x400000>; |
706 | reg-names = "mpu", "dat"; | 706 | reg-names = "mpu", "dat"; |
707 | interrupts = <82>, <83>; | 707 | interrupts = <82>, <83>; |
708 | interrupts-names = "tx", "rx"; | 708 | interrupt-names = "tx", "rx"; |
709 | status = "disabled"; | 709 | status = "disabled"; |
710 | dmas = <&edma 10>, | 710 | dmas = <&edma 10>, |
711 | <&edma 11>; | 711 | <&edma 11>; |
712 | dma-names = "tx", "rx"; | 712 | dma-names = "tx", "rx"; |
713 | }; | 713 | }; |
714 | 714 | ||
715 | elm: elm@48080000 { | 715 | elm: elm@48080000 { |
716 | compatible = "ti,am3352-elm"; | 716 | compatible = "ti,am3352-elm"; |
717 | reg = <0x48080000 0x2000>; | 717 | reg = <0x48080000 0x2000>; |
718 | interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; | 718 | interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; |
719 | ti,hwmods = "elm"; | 719 | ti,hwmods = "elm"; |
720 | clocks = <&l4ls_gclk>; | 720 | clocks = <&l4ls_gclk>; |
721 | clock-names = "fck"; | 721 | clock-names = "fck"; |
722 | status = "disabled"; | 722 | status = "disabled"; |
723 | }; | 723 | }; |
724 | 724 | ||
725 | gpmc: gpmc@50000000 { | 725 | gpmc: gpmc@50000000 { |
726 | compatible = "ti,am3352-gpmc"; | 726 | compatible = "ti,am3352-gpmc"; |
727 | ti,hwmods = "gpmc"; | 727 | ti,hwmods = "gpmc"; |
728 | clocks = <&l3s_gclk>; | 728 | clocks = <&l3s_gclk>; |
729 | clock-names = "fck"; | 729 | clock-names = "fck"; |
730 | reg = <0x50000000 0x2000>; | 730 | reg = <0x50000000 0x2000>; |
731 | interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; | 731 | interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; |
732 | gpmc,num-cs = <7>; | 732 | gpmc,num-cs = <7>; |
733 | gpmc,num-waitpins = <2>; | 733 | gpmc,num-waitpins = <2>; |
734 | #address-cells = <2>; | 734 | #address-cells = <2>; |
735 | #size-cells = <1>; | 735 | #size-cells = <1>; |
736 | status = "disabled"; | 736 | status = "disabled"; |
737 | }; | 737 | }; |
738 | }; | 738 | }; |
739 | }; | 739 | }; |
740 | 740 | ||
741 | /include/ "am43xx-clocks.dtsi" | 741 | /include/ "am43xx-clocks.dtsi" |
742 | 742 |
arch/arm/boot/dts/stih415-pinctrl.dtsi
1 | /* | 1 | /* |
2 | * Copyright (C) 2013 STMicroelectronics (R&D) Limited. | 2 | * Copyright (C) 2013 STMicroelectronics (R&D) Limited. |
3 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | 3 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * publishhed by the Free Software Foundation. | 7 | * publishhed by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | #include "st-pincfg.h" | 9 | #include "st-pincfg.h" |
10 | #include <dt-bindings/interrupt-controller/arm-gic.h> | 10 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
11 | / { | 11 | / { |
12 | 12 | ||
13 | aliases { | 13 | aliases { |
14 | gpio0 = &PIO0; | 14 | gpio0 = &PIO0; |
15 | gpio1 = &PIO1; | 15 | gpio1 = &PIO1; |
16 | gpio2 = &PIO2; | 16 | gpio2 = &PIO2; |
17 | gpio3 = &PIO3; | 17 | gpio3 = &PIO3; |
18 | gpio4 = &PIO4; | 18 | gpio4 = &PIO4; |
19 | gpio5 = &PIO5; | 19 | gpio5 = &PIO5; |
20 | gpio6 = &PIO6; | 20 | gpio6 = &PIO6; |
21 | gpio7 = &PIO7; | 21 | gpio7 = &PIO7; |
22 | gpio8 = &PIO8; | 22 | gpio8 = &PIO8; |
23 | gpio9 = &PIO9; | 23 | gpio9 = &PIO9; |
24 | gpio10 = &PIO10; | 24 | gpio10 = &PIO10; |
25 | gpio11 = &PIO11; | 25 | gpio11 = &PIO11; |
26 | gpio12 = &PIO12; | 26 | gpio12 = &PIO12; |
27 | gpio13 = &PIO13; | 27 | gpio13 = &PIO13; |
28 | gpio14 = &PIO14; | 28 | gpio14 = &PIO14; |
29 | gpio15 = &PIO15; | 29 | gpio15 = &PIO15; |
30 | gpio16 = &PIO16; | 30 | gpio16 = &PIO16; |
31 | gpio17 = &PIO17; | 31 | gpio17 = &PIO17; |
32 | gpio18 = &PIO18; | 32 | gpio18 = &PIO18; |
33 | gpio19 = &PIO100; | 33 | gpio19 = &PIO100; |
34 | gpio20 = &PIO101; | 34 | gpio20 = &PIO101; |
35 | gpio21 = &PIO102; | 35 | gpio21 = &PIO102; |
36 | gpio22 = &PIO103; | 36 | gpio22 = &PIO103; |
37 | gpio23 = &PIO104; | 37 | gpio23 = &PIO104; |
38 | gpio24 = &PIO105; | 38 | gpio24 = &PIO105; |
39 | gpio25 = &PIO106; | 39 | gpio25 = &PIO106; |
40 | gpio26 = &PIO107; | 40 | gpio26 = &PIO107; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | soc { | 43 | soc { |
44 | pin-controller-sbc { | 44 | pin-controller-sbc { |
45 | #address-cells = <1>; | 45 | #address-cells = <1>; |
46 | #size-cells = <1>; | 46 | #size-cells = <1>; |
47 | compatible = "st,stih415-sbc-pinctrl"; | 47 | compatible = "st,stih415-sbc-pinctrl"; |
48 | st,syscfg = <&syscfg_sbc>; | 48 | st,syscfg = <&syscfg_sbc>; |
49 | reg = <0xfe61f080 0x4>; | 49 | reg = <0xfe61f080 0x4>; |
50 | reg-names = "irqmux"; | 50 | reg-names = "irqmux"; |
51 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; | 51 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; |
52 | interrupts-names = "irqmux"; | 52 | interrupt-names = "irqmux"; |
53 | ranges = <0 0xfe610000 0x5000>; | 53 | ranges = <0 0xfe610000 0x5000>; |
54 | 54 | ||
55 | PIO0: gpio@fe610000 { | 55 | PIO0: gpio@fe610000 { |
56 | gpio-controller; | 56 | gpio-controller; |
57 | #gpio-cells = <1>; | 57 | #gpio-cells = <1>; |
58 | interrupt-controller; | 58 | interrupt-controller; |
59 | #interrupt-cells = <2>; | 59 | #interrupt-cells = <2>; |
60 | reg = <0 0x100>; | 60 | reg = <0 0x100>; |
61 | st,bank-name = "PIO0"; | 61 | st,bank-name = "PIO0"; |
62 | }; | 62 | }; |
63 | PIO1: gpio@fe611000 { | 63 | PIO1: gpio@fe611000 { |
64 | gpio-controller; | 64 | gpio-controller; |
65 | #gpio-cells = <1>; | 65 | #gpio-cells = <1>; |
66 | interrupt-controller; | 66 | interrupt-controller; |
67 | #interrupt-cells = <2>; | 67 | #interrupt-cells = <2>; |
68 | reg = <0x1000 0x100>; | 68 | reg = <0x1000 0x100>; |
69 | st,bank-name = "PIO1"; | 69 | st,bank-name = "PIO1"; |
70 | }; | 70 | }; |
71 | PIO2: gpio@fe612000 { | 71 | PIO2: gpio@fe612000 { |
72 | gpio-controller; | 72 | gpio-controller; |
73 | #gpio-cells = <1>; | 73 | #gpio-cells = <1>; |
74 | interrupt-controller; | 74 | interrupt-controller; |
75 | #interrupt-cells = <2>; | 75 | #interrupt-cells = <2>; |
76 | reg = <0x2000 0x100>; | 76 | reg = <0x2000 0x100>; |
77 | st,bank-name = "PIO2"; | 77 | st,bank-name = "PIO2"; |
78 | }; | 78 | }; |
79 | PIO3: gpio@fe613000 { | 79 | PIO3: gpio@fe613000 { |
80 | gpio-controller; | 80 | gpio-controller; |
81 | #gpio-cells = <1>; | 81 | #gpio-cells = <1>; |
82 | interrupt-controller; | 82 | interrupt-controller; |
83 | #interrupt-cells = <2>; | 83 | #interrupt-cells = <2>; |
84 | reg = <0x3000 0x100>; | 84 | reg = <0x3000 0x100>; |
85 | st,bank-name = "PIO3"; | 85 | st,bank-name = "PIO3"; |
86 | }; | 86 | }; |
87 | PIO4: gpio@fe614000 { | 87 | PIO4: gpio@fe614000 { |
88 | gpio-controller; | 88 | gpio-controller; |
89 | #gpio-cells = <1>; | 89 | #gpio-cells = <1>; |
90 | interrupt-controller; | 90 | interrupt-controller; |
91 | #interrupt-cells = <2>; | 91 | #interrupt-cells = <2>; |
92 | reg = <0x4000 0x100>; | 92 | reg = <0x4000 0x100>; |
93 | st,bank-name = "PIO4"; | 93 | st,bank-name = "PIO4"; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | sbc_serial1 { | 96 | sbc_serial1 { |
97 | pinctrl_sbc_serial1:sbc_serial1 { | 97 | pinctrl_sbc_serial1:sbc_serial1 { |
98 | st,pins { | 98 | st,pins { |
99 | tx = <&PIO2 6 ALT3 OUT>; | 99 | tx = <&PIO2 6 ALT3 OUT>; |
100 | rx = <&PIO2 7 ALT3 IN>; | 100 | rx = <&PIO2 7 ALT3 IN>; |
101 | }; | 101 | }; |
102 | }; | 102 | }; |
103 | }; | 103 | }; |
104 | 104 | ||
105 | sbc_i2c0 { | 105 | sbc_i2c0 { |
106 | pinctrl_sbc_i2c0_default: sbc_i2c0-default { | 106 | pinctrl_sbc_i2c0_default: sbc_i2c0-default { |
107 | st,pins { | 107 | st,pins { |
108 | sda = <&PIO4 6 ALT1 BIDIR>; | 108 | sda = <&PIO4 6 ALT1 BIDIR>; |
109 | scl = <&PIO4 5 ALT1 BIDIR>; | 109 | scl = <&PIO4 5 ALT1 BIDIR>; |
110 | }; | 110 | }; |
111 | }; | 111 | }; |
112 | }; | 112 | }; |
113 | 113 | ||
114 | sbc_i2c1 { | 114 | sbc_i2c1 { |
115 | pinctrl_sbc_i2c1_default: sbc_i2c1-default { | 115 | pinctrl_sbc_i2c1_default: sbc_i2c1-default { |
116 | st,pins { | 116 | st,pins { |
117 | sda = <&PIO3 2 ALT2 BIDIR>; | 117 | sda = <&PIO3 2 ALT2 BIDIR>; |
118 | scl = <&PIO3 1 ALT2 BIDIR>; | 118 | scl = <&PIO3 1 ALT2 BIDIR>; |
119 | }; | 119 | }; |
120 | }; | 120 | }; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | rc{ | 123 | rc{ |
124 | pinctrl_ir: ir0 { | 124 | pinctrl_ir: ir0 { |
125 | st,pins { | 125 | st,pins { |
126 | ir = <&PIO4 0 ALT2 IN>; | 126 | ir = <&PIO4 0 ALT2 IN>; |
127 | }; | 127 | }; |
128 | }; | 128 | }; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | gmac1 { | 131 | gmac1 { |
132 | pinctrl_mii1: mii1 { | 132 | pinctrl_mii1: mii1 { |
133 | st,pins { | 133 | st,pins { |
134 | txd0 = <&PIO0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 134 | txd0 = <&PIO0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
135 | txd1 = <&PIO0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 135 | txd1 = <&PIO0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
136 | txd2 = <&PIO0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 136 | txd2 = <&PIO0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
137 | txd3 = <&PIO0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 137 | txd3 = <&PIO0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
138 | txer = <&PIO0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 138 | txer = <&PIO0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
139 | txen = <&PIO0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 139 | txen = <&PIO0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
140 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; | 140 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; |
141 | col = <&PIO0 7 ALT1 IN BYPASS 1000>; | 141 | col = <&PIO0 7 ALT1 IN BYPASS 1000>; |
142 | mdio = <&PIO1 0 ALT1 OUT BYPASS 0>; | 142 | mdio = <&PIO1 0 ALT1 OUT BYPASS 0>; |
143 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; | 143 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; |
144 | crs = <&PIO1 2 ALT1 IN BYPASS 1000>; | 144 | crs = <&PIO1 2 ALT1 IN BYPASS 1000>; |
145 | mdint = <&PIO1 3 ALT1 IN BYPASS 0>; | 145 | mdint = <&PIO1 3 ALT1 IN BYPASS 0>; |
146 | rxd0 = <&PIO1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 146 | rxd0 = <&PIO1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
147 | rxd1 = <&PIO1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 147 | rxd1 = <&PIO1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
148 | rxd2 = <&PIO1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 148 | rxd2 = <&PIO1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
149 | rxd3 = <&PIO1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 149 | rxd3 = <&PIO1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
150 | rxdv = <&PIO2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 150 | rxdv = <&PIO2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
151 | rx_er = <&PIO2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 151 | rx_er = <&PIO2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
152 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; | 152 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; |
153 | phyclk = <&PIO2 3 ALT1 IN NICLK 1000 CLK_A>; | 153 | phyclk = <&PIO2 3 ALT1 IN NICLK 1000 CLK_A>; |
154 | }; | 154 | }; |
155 | }; | 155 | }; |
156 | 156 | ||
157 | pinctrl_rgmii1: rgmii1-0 { | 157 | pinctrl_rgmii1: rgmii1-0 { |
158 | st,pins { | 158 | st,pins { |
159 | txd0 = <&PIO0 0 ALT1 OUT DE_IO 1000 CLK_A>; | 159 | txd0 = <&PIO0 0 ALT1 OUT DE_IO 1000 CLK_A>; |
160 | txd1 = <&PIO0 1 ALT1 OUT DE_IO 1000 CLK_A>; | 160 | txd1 = <&PIO0 1 ALT1 OUT DE_IO 1000 CLK_A>; |
161 | txd2 = <&PIO0 2 ALT1 OUT DE_IO 1000 CLK_A>; | 161 | txd2 = <&PIO0 2 ALT1 OUT DE_IO 1000 CLK_A>; |
162 | txd3 = <&PIO0 3 ALT1 OUT DE_IO 1000 CLK_A>; | 162 | txd3 = <&PIO0 3 ALT1 OUT DE_IO 1000 CLK_A>; |
163 | txen = <&PIO0 5 ALT1 OUT DE_IO 0 CLK_A>; | 163 | txen = <&PIO0 5 ALT1 OUT DE_IO 0 CLK_A>; |
164 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; | 164 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; |
165 | mdio = <&PIO1 0 ALT1 OUT BYPASS 0>; | 165 | mdio = <&PIO1 0 ALT1 OUT BYPASS 0>; |
166 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; | 166 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; |
167 | rxd0 = <&PIO1 4 ALT1 IN DE_IO 0 CLK_A>; | 167 | rxd0 = <&PIO1 4 ALT1 IN DE_IO 0 CLK_A>; |
168 | rxd1 = <&PIO1 5 ALT1 IN DE_IO 0 CLK_A>; | 168 | rxd1 = <&PIO1 5 ALT1 IN DE_IO 0 CLK_A>; |
169 | rxd2 = <&PIO1 6 ALT1 IN DE_IO 0 CLK_A>; | 169 | rxd2 = <&PIO1 6 ALT1 IN DE_IO 0 CLK_A>; |
170 | rxd3 = <&PIO1 7 ALT1 IN DE_IO 0 CLK_A>; | 170 | rxd3 = <&PIO1 7 ALT1 IN DE_IO 0 CLK_A>; |
171 | 171 | ||
172 | rxdv = <&PIO2 0 ALT1 IN DE_IO 500 CLK_A>; | 172 | rxdv = <&PIO2 0 ALT1 IN DE_IO 500 CLK_A>; |
173 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; | 173 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; |
174 | phyclk = <&PIO2 3 ALT4 OUT NICLK 0 CLK_B>; | 174 | phyclk = <&PIO2 3 ALT4 OUT NICLK 0 CLK_B>; |
175 | 175 | ||
176 | clk125= <&PIO3 7 ALT4 IN NICLK 0 CLK_A>; | 176 | clk125= <&PIO3 7 ALT4 IN NICLK 0 CLK_A>; |
177 | }; | 177 | }; |
178 | }; | 178 | }; |
179 | }; | 179 | }; |
180 | }; | 180 | }; |
181 | 181 | ||
182 | pin-controller-front { | 182 | pin-controller-front { |
183 | #address-cells = <1>; | 183 | #address-cells = <1>; |
184 | #size-cells = <1>; | 184 | #size-cells = <1>; |
185 | compatible = "st,stih415-front-pinctrl"; | 185 | compatible = "st,stih415-front-pinctrl"; |
186 | st,syscfg = <&syscfg_front>; | 186 | st,syscfg = <&syscfg_front>; |
187 | reg = <0xfee0f080 0x4>; | 187 | reg = <0xfee0f080 0x4>; |
188 | reg-names = "irqmux"; | 188 | reg-names = "irqmux"; |
189 | interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>; | 189 | interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>; |
190 | interrupts-names = "irqmux"; | 190 | interrupt-names = "irqmux"; |
191 | ranges = <0 0xfee00000 0x8000>; | 191 | ranges = <0 0xfee00000 0x8000>; |
192 | 192 | ||
193 | PIO5: gpio@fee00000 { | 193 | PIO5: gpio@fee00000 { |
194 | gpio-controller; | 194 | gpio-controller; |
195 | #gpio-cells = <1>; | 195 | #gpio-cells = <1>; |
196 | interrupt-controller; | 196 | interrupt-controller; |
197 | #interrupt-cells = <2>; | 197 | #interrupt-cells = <2>; |
198 | reg = <0 0x100>; | 198 | reg = <0 0x100>; |
199 | st,bank-name = "PIO5"; | 199 | st,bank-name = "PIO5"; |
200 | }; | 200 | }; |
201 | PIO6: gpio@fee01000 { | 201 | PIO6: gpio@fee01000 { |
202 | gpio-controller; | 202 | gpio-controller; |
203 | #gpio-cells = <1>; | 203 | #gpio-cells = <1>; |
204 | interrupt-controller; | 204 | interrupt-controller; |
205 | #interrupt-cells = <2>; | 205 | #interrupt-cells = <2>; |
206 | reg = <0x1000 0x100>; | 206 | reg = <0x1000 0x100>; |
207 | st,bank-name = "PIO6"; | 207 | st,bank-name = "PIO6"; |
208 | }; | 208 | }; |
209 | PIO7: gpio@fee02000 { | 209 | PIO7: gpio@fee02000 { |
210 | gpio-controller; | 210 | gpio-controller; |
211 | #gpio-cells = <1>; | 211 | #gpio-cells = <1>; |
212 | interrupt-controller; | 212 | interrupt-controller; |
213 | #interrupt-cells = <2>; | 213 | #interrupt-cells = <2>; |
214 | reg = <0x2000 0x100>; | 214 | reg = <0x2000 0x100>; |
215 | st,bank-name = "PIO7"; | 215 | st,bank-name = "PIO7"; |
216 | }; | 216 | }; |
217 | PIO8: gpio@fee03000 { | 217 | PIO8: gpio@fee03000 { |
218 | gpio-controller; | 218 | gpio-controller; |
219 | #gpio-cells = <1>; | 219 | #gpio-cells = <1>; |
220 | interrupt-controller; | 220 | interrupt-controller; |
221 | #interrupt-cells = <2>; | 221 | #interrupt-cells = <2>; |
222 | reg = <0x3000 0x100>; | 222 | reg = <0x3000 0x100>; |
223 | st,bank-name = "PIO8"; | 223 | st,bank-name = "PIO8"; |
224 | }; | 224 | }; |
225 | PIO9: gpio@fee04000 { | 225 | PIO9: gpio@fee04000 { |
226 | gpio-controller; | 226 | gpio-controller; |
227 | #gpio-cells = <1>; | 227 | #gpio-cells = <1>; |
228 | interrupt-controller; | 228 | interrupt-controller; |
229 | #interrupt-cells = <2>; | 229 | #interrupt-cells = <2>; |
230 | reg = <0x4000 0x100>; | 230 | reg = <0x4000 0x100>; |
231 | st,bank-name = "PIO9"; | 231 | st,bank-name = "PIO9"; |
232 | }; | 232 | }; |
233 | PIO10: gpio@fee05000 { | 233 | PIO10: gpio@fee05000 { |
234 | gpio-controller; | 234 | gpio-controller; |
235 | #gpio-cells = <1>; | 235 | #gpio-cells = <1>; |
236 | interrupt-controller; | 236 | interrupt-controller; |
237 | #interrupt-cells = <2>; | 237 | #interrupt-cells = <2>; |
238 | reg = <0x5000 0x100>; | 238 | reg = <0x5000 0x100>; |
239 | st,bank-name = "PIO10"; | 239 | st,bank-name = "PIO10"; |
240 | }; | 240 | }; |
241 | PIO11: gpio@fee06000 { | 241 | PIO11: gpio@fee06000 { |
242 | gpio-controller; | 242 | gpio-controller; |
243 | #gpio-cells = <1>; | 243 | #gpio-cells = <1>; |
244 | interrupt-controller; | 244 | interrupt-controller; |
245 | #interrupt-cells = <2>; | 245 | #interrupt-cells = <2>; |
246 | reg = <0x6000 0x100>; | 246 | reg = <0x6000 0x100>; |
247 | st,bank-name = "PIO11"; | 247 | st,bank-name = "PIO11"; |
248 | }; | 248 | }; |
249 | PIO12: gpio@fee07000 { | 249 | PIO12: gpio@fee07000 { |
250 | gpio-controller; | 250 | gpio-controller; |
251 | #gpio-cells = <1>; | 251 | #gpio-cells = <1>; |
252 | interrupt-controller; | 252 | interrupt-controller; |
253 | #interrupt-cells = <2>; | 253 | #interrupt-cells = <2>; |
254 | reg = <0x7000 0x100>; | 254 | reg = <0x7000 0x100>; |
255 | st,bank-name = "PIO12"; | 255 | st,bank-name = "PIO12"; |
256 | }; | 256 | }; |
257 | 257 | ||
258 | i2c0 { | 258 | i2c0 { |
259 | pinctrl_i2c0_default: i2c0-default { | 259 | pinctrl_i2c0_default: i2c0-default { |
260 | st,pins { | 260 | st,pins { |
261 | sda = <&PIO9 3 ALT1 BIDIR>; | 261 | sda = <&PIO9 3 ALT1 BIDIR>; |
262 | scl = <&PIO9 2 ALT1 BIDIR>; | 262 | scl = <&PIO9 2 ALT1 BIDIR>; |
263 | }; | 263 | }; |
264 | }; | 264 | }; |
265 | }; | 265 | }; |
266 | 266 | ||
267 | i2c1 { | 267 | i2c1 { |
268 | pinctrl_i2c1_default: i2c1-default { | 268 | pinctrl_i2c1_default: i2c1-default { |
269 | st,pins { | 269 | st,pins { |
270 | sda = <&PIO12 1 ALT1 BIDIR>; | 270 | sda = <&PIO12 1 ALT1 BIDIR>; |
271 | scl = <&PIO12 0 ALT1 BIDIR>; | 271 | scl = <&PIO12 0 ALT1 BIDIR>; |
272 | }; | 272 | }; |
273 | }; | 273 | }; |
274 | }; | 274 | }; |
275 | }; | 275 | }; |
276 | 276 | ||
277 | pin-controller-rear { | 277 | pin-controller-rear { |
278 | #address-cells = <1>; | 278 | #address-cells = <1>; |
279 | #size-cells = <1>; | 279 | #size-cells = <1>; |
280 | compatible = "st,stih415-rear-pinctrl"; | 280 | compatible = "st,stih415-rear-pinctrl"; |
281 | st,syscfg = <&syscfg_rear>; | 281 | st,syscfg = <&syscfg_rear>; |
282 | reg = <0xfe82f080 0x4>; | 282 | reg = <0xfe82f080 0x4>; |
283 | reg-names = "irqmux"; | 283 | reg-names = "irqmux"; |
284 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; | 284 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; |
285 | interrupts-names = "irqmux"; | 285 | interrupt-names = "irqmux"; |
286 | ranges = <0 0xfe820000 0x8000>; | 286 | ranges = <0 0xfe820000 0x8000>; |
287 | 287 | ||
288 | PIO13: gpio@fe820000 { | 288 | PIO13: gpio@fe820000 { |
289 | gpio-controller; | 289 | gpio-controller; |
290 | #gpio-cells = <1>; | 290 | #gpio-cells = <1>; |
291 | interrupt-controller; | 291 | interrupt-controller; |
292 | #interrupt-cells = <2>; | 292 | #interrupt-cells = <2>; |
293 | reg = <0 0x100>; | 293 | reg = <0 0x100>; |
294 | st,bank-name = "PIO13"; | 294 | st,bank-name = "PIO13"; |
295 | }; | 295 | }; |
296 | PIO14: gpio@fe821000 { | 296 | PIO14: gpio@fe821000 { |
297 | gpio-controller; | 297 | gpio-controller; |
298 | #gpio-cells = <1>; | 298 | #gpio-cells = <1>; |
299 | interrupt-controller; | 299 | interrupt-controller; |
300 | #interrupt-cells = <2>; | 300 | #interrupt-cells = <2>; |
301 | reg = <0x1000 0x100>; | 301 | reg = <0x1000 0x100>; |
302 | st,bank-name = "PIO14"; | 302 | st,bank-name = "PIO14"; |
303 | }; | 303 | }; |
304 | PIO15: gpio@fe822000 { | 304 | PIO15: gpio@fe822000 { |
305 | gpio-controller; | 305 | gpio-controller; |
306 | #gpio-cells = <1>; | 306 | #gpio-cells = <1>; |
307 | interrupt-controller; | 307 | interrupt-controller; |
308 | #interrupt-cells = <2>; | 308 | #interrupt-cells = <2>; |
309 | reg = <0x2000 0x100>; | 309 | reg = <0x2000 0x100>; |
310 | st,bank-name = "PIO15"; | 310 | st,bank-name = "PIO15"; |
311 | }; | 311 | }; |
312 | PIO16: gpio@fe823000 { | 312 | PIO16: gpio@fe823000 { |
313 | gpio-controller; | 313 | gpio-controller; |
314 | #gpio-cells = <1>; | 314 | #gpio-cells = <1>; |
315 | interrupt-controller; | 315 | interrupt-controller; |
316 | #interrupt-cells = <2>; | 316 | #interrupt-cells = <2>; |
317 | reg = <0x3000 0x100>; | 317 | reg = <0x3000 0x100>; |
318 | st,bank-name = "PIO16"; | 318 | st,bank-name = "PIO16"; |
319 | }; | 319 | }; |
320 | PIO17: gpio@fe824000 { | 320 | PIO17: gpio@fe824000 { |
321 | gpio-controller; | 321 | gpio-controller; |
322 | #gpio-cells = <1>; | 322 | #gpio-cells = <1>; |
323 | interrupt-controller; | 323 | interrupt-controller; |
324 | #interrupt-cells = <2>; | 324 | #interrupt-cells = <2>; |
325 | reg = <0x4000 0x100>; | 325 | reg = <0x4000 0x100>; |
326 | st,bank-name = "PIO17"; | 326 | st,bank-name = "PIO17"; |
327 | }; | 327 | }; |
328 | PIO18: gpio@fe825000 { | 328 | PIO18: gpio@fe825000 { |
329 | gpio-controller; | 329 | gpio-controller; |
330 | #gpio-cells = <1>; | 330 | #gpio-cells = <1>; |
331 | interrupt-controller; | 331 | interrupt-controller; |
332 | #interrupt-cells = <2>; | 332 | #interrupt-cells = <2>; |
333 | reg = <0x5000 0x100>; | 333 | reg = <0x5000 0x100>; |
334 | st,bank-name = "PIO18"; | 334 | st,bank-name = "PIO18"; |
335 | }; | 335 | }; |
336 | 336 | ||
337 | serial2 { | 337 | serial2 { |
338 | pinctrl_serial2: serial2-0 { | 338 | pinctrl_serial2: serial2-0 { |
339 | st,pins { | 339 | st,pins { |
340 | tx = <&PIO17 4 ALT2 OUT>; | 340 | tx = <&PIO17 4 ALT2 OUT>; |
341 | rx = <&PIO17 5 ALT2 IN>; | 341 | rx = <&PIO17 5 ALT2 IN>; |
342 | }; | 342 | }; |
343 | }; | 343 | }; |
344 | }; | 344 | }; |
345 | 345 | ||
346 | gmac0{ | 346 | gmac0{ |
347 | pinctrl_mii0: mii0 { | 347 | pinctrl_mii0: mii0 { |
348 | st,pins { | 348 | st,pins { |
349 | mdint = <&PIO13 6 ALT2 IN BYPASS 0>; | 349 | mdint = <&PIO13 6 ALT2 IN BYPASS 0>; |
350 | txen = <&PIO13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 350 | txen = <&PIO13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
351 | 351 | ||
352 | txd0 = <&PIO14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 352 | txd0 = <&PIO14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
353 | txd1 = <&PIO14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 353 | txd1 = <&PIO14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
354 | txd2 = <&PIO14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>; | 354 | txd2 = <&PIO14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>; |
355 | txd3 = <&PIO14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>; | 355 | txd3 = <&PIO14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>; |
356 | 356 | ||
357 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; | 357 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; |
358 | txer = <&PIO15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 358 | txer = <&PIO15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
359 | crs = <&PIO15 2 ALT2 IN BYPASS 1000>; | 359 | crs = <&PIO15 2 ALT2 IN BYPASS 1000>; |
360 | col = <&PIO15 3 ALT2 IN BYPASS 1000>; | 360 | col = <&PIO15 3 ALT2 IN BYPASS 1000>; |
361 | mdio = <&PIO15 4 ALT2 OUT BYPASS 3000>; | 361 | mdio = <&PIO15 4 ALT2 OUT BYPASS 3000>; |
362 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; | 362 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; |
363 | 363 | ||
364 | rxd0 = <&PIO16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 364 | rxd0 = <&PIO16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
365 | rxd1 = <&PIO16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 365 | rxd1 = <&PIO16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
366 | rxd2 = <&PIO16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 366 | rxd2 = <&PIO16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
367 | rxd3 = <&PIO16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 367 | rxd3 = <&PIO16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
368 | rxdv = <&PIO15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 368 | rxdv = <&PIO15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
369 | rx_er = <&PIO15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 369 | rx_er = <&PIO15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
370 | rxclk = <&PIO17 0 ALT2 IN NICLK 0 CLK_A>; | 370 | rxclk = <&PIO17 0 ALT2 IN NICLK 0 CLK_A>; |
371 | phyclk = <&PIO13 5 ALT2 OUT NICLK 1000 CLK_A>; | 371 | phyclk = <&PIO13 5 ALT2 OUT NICLK 1000 CLK_A>; |
372 | 372 | ||
373 | }; | 373 | }; |
374 | }; | 374 | }; |
375 | 375 | ||
376 | pinctrl_gmii0: gmii0 { | 376 | pinctrl_gmii0: gmii0 { |
377 | st,pins { | 377 | st,pins { |
378 | mdint = <&PIO13 6 ALT2 IN BYPASS 0>; | 378 | mdint = <&PIO13 6 ALT2 IN BYPASS 0>; |
379 | mdio = <&PIO15 4 ALT2 OUT BYPASS 3000>; | 379 | mdio = <&PIO15 4 ALT2 OUT BYPASS 3000>; |
380 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; | 380 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; |
381 | txen = <&PIO13 7 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; | 381 | txen = <&PIO13 7 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; |
382 | 382 | ||
383 | txd0 = <&PIO14 0 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; | 383 | txd0 = <&PIO14 0 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; |
384 | txd1 = <&PIO14 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; | 384 | txd1 = <&PIO14 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; |
385 | txd2 = <&PIO14 2 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; | 385 | txd2 = <&PIO14 2 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; |
386 | txd3 = <&PIO14 3 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; | 386 | txd3 = <&PIO14 3 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; |
387 | txd4 = <&PIO14 4 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; | 387 | txd4 = <&PIO14 4 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; |
388 | txd5 = <&PIO14 5 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; | 388 | txd5 = <&PIO14 5 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; |
389 | txd6 = <&PIO14 6 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; | 389 | txd6 = <&PIO14 6 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; |
390 | txd7 = <&PIO14 7 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; | 390 | txd7 = <&PIO14 7 ALT2 OUT SE_NICLK_IO 3000 CLK_B>; |
391 | 391 | ||
392 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; | 392 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; |
393 | txer = <&PIO15 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; | 393 | txer = <&PIO15 1 ALT2 OUT SE_NICLK_IO 3000 CLK_A>; |
394 | crs = <&PIO15 2 ALT2 IN BYPASS 1000>; | 394 | crs = <&PIO15 2 ALT2 IN BYPASS 1000>; |
395 | col = <&PIO15 3 ALT2 IN BYPASS 1000>; | 395 | col = <&PIO15 3 ALT2 IN BYPASS 1000>; |
396 | rxdv = <&PIO15 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 396 | rxdv = <&PIO15 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
397 | rx_er = <&PIO15 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 397 | rx_er = <&PIO15 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
398 | 398 | ||
399 | rxd0 = <&PIO16 0 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 399 | rxd0 = <&PIO16 0 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
400 | rxd1 = <&PIO16 1 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 400 | rxd1 = <&PIO16 1 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
401 | rxd2 = <&PIO16 2 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 401 | rxd2 = <&PIO16 2 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
402 | rxd3 = <&PIO16 3 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 402 | rxd3 = <&PIO16 3 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
403 | rxd4 = <&PIO16 4 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 403 | rxd4 = <&PIO16 4 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
404 | rxd5 = <&PIO16 5 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 404 | rxd5 = <&PIO16 5 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
405 | rxd6 = <&PIO16 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 405 | rxd6 = <&PIO16 6 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
406 | rxd7 = <&PIO16 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>; | 406 | rxd7 = <&PIO16 7 ALT2 IN SE_NICLK_IO 1500 CLK_A>; |
407 | 407 | ||
408 | rxclk = <&PIO17 0 ALT2 IN NICLK 0 CLK_A>; | 408 | rxclk = <&PIO17 0 ALT2 IN NICLK 0 CLK_A>; |
409 | clk125 = <&PIO17 6 ALT1 IN NICLK 0 CLK_A>; | 409 | clk125 = <&PIO17 6 ALT1 IN NICLK 0 CLK_A>; |
410 | phyclk = <&PIO13 5 ALT4 OUT NICLK 0 CLK_B>; | 410 | phyclk = <&PIO13 5 ALT4 OUT NICLK 0 CLK_B>; |
411 | 411 | ||
412 | 412 | ||
413 | }; | 413 | }; |
414 | }; | 414 | }; |
415 | }; | 415 | }; |
416 | }; | 416 | }; |
417 | 417 | ||
418 | pin-controller-left { | 418 | pin-controller-left { |
419 | #address-cells = <1>; | 419 | #address-cells = <1>; |
420 | #size-cells = <1>; | 420 | #size-cells = <1>; |
421 | compatible = "st,stih415-left-pinctrl"; | 421 | compatible = "st,stih415-left-pinctrl"; |
422 | st,syscfg = <&syscfg_left>; | 422 | st,syscfg = <&syscfg_left>; |
423 | reg = <0xfd6bf080 0x4>; | 423 | reg = <0xfd6bf080 0x4>; |
424 | reg-names = "irqmux"; | 424 | reg-names = "irqmux"; |
425 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; | 425 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; |
426 | interrupts-names = "irqmux"; | 426 | interrupt-names = "irqmux"; |
427 | ranges = <0 0xfd6b0000 0x3000>; | 427 | ranges = <0 0xfd6b0000 0x3000>; |
428 | 428 | ||
429 | PIO100: gpio@fd6b0000 { | 429 | PIO100: gpio@fd6b0000 { |
430 | gpio-controller; | 430 | gpio-controller; |
431 | #gpio-cells = <1>; | 431 | #gpio-cells = <1>; |
432 | interrupt-controller; | 432 | interrupt-controller; |
433 | #interrupt-cells = <2>; | 433 | #interrupt-cells = <2>; |
434 | reg = <0 0x100>; | 434 | reg = <0 0x100>; |
435 | st,bank-name = "PIO100"; | 435 | st,bank-name = "PIO100"; |
436 | }; | 436 | }; |
437 | PIO101: gpio@fd6b1000 { | 437 | PIO101: gpio@fd6b1000 { |
438 | gpio-controller; | 438 | gpio-controller; |
439 | #gpio-cells = <1>; | 439 | #gpio-cells = <1>; |
440 | interrupt-controller; | 440 | interrupt-controller; |
441 | #interrupt-cells = <2>; | 441 | #interrupt-cells = <2>; |
442 | reg = <0x1000 0x100>; | 442 | reg = <0x1000 0x100>; |
443 | st,bank-name = "PIO101"; | 443 | st,bank-name = "PIO101"; |
444 | }; | 444 | }; |
445 | PIO102: gpio@fd6b2000 { | 445 | PIO102: gpio@fd6b2000 { |
446 | gpio-controller; | 446 | gpio-controller; |
447 | #gpio-cells = <1>; | 447 | #gpio-cells = <1>; |
448 | interrupt-controller; | 448 | interrupt-controller; |
449 | #interrupt-cells = <2>; | 449 | #interrupt-cells = <2>; |
450 | reg = <0x2000 0x100>; | 450 | reg = <0x2000 0x100>; |
451 | st,bank-name = "PIO102"; | 451 | st,bank-name = "PIO102"; |
452 | }; | 452 | }; |
453 | }; | 453 | }; |
454 | 454 | ||
455 | pin-controller-right { | 455 | pin-controller-right { |
456 | #address-cells = <1>; | 456 | #address-cells = <1>; |
457 | #size-cells = <1>; | 457 | #size-cells = <1>; |
458 | compatible = "st,stih415-right-pinctrl"; | 458 | compatible = "st,stih415-right-pinctrl"; |
459 | st,syscfg = <&syscfg_right>; | 459 | st,syscfg = <&syscfg_right>; |
460 | reg = <0xfd33f080 0x4>; | 460 | reg = <0xfd33f080 0x4>; |
461 | reg-names = "irqmux"; | 461 | reg-names = "irqmux"; |
462 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; | 462 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; |
463 | interrupts-names = "irqmux"; | 463 | interrupt-names = "irqmux"; |
464 | ranges = <0 0xfd330000 0x5000>; | 464 | ranges = <0 0xfd330000 0x5000>; |
465 | 465 | ||
466 | PIO103: gpio@fd330000 { | 466 | PIO103: gpio@fd330000 { |
467 | gpio-controller; | 467 | gpio-controller; |
468 | #gpio-cells = <1>; | 468 | #gpio-cells = <1>; |
469 | interrupt-controller; | 469 | interrupt-controller; |
470 | #interrupt-cells = <2>; | 470 | #interrupt-cells = <2>; |
471 | reg = <0 0x100>; | 471 | reg = <0 0x100>; |
472 | st,bank-name = "PIO103"; | 472 | st,bank-name = "PIO103"; |
473 | }; | 473 | }; |
474 | PIO104: gpio@fd331000 { | 474 | PIO104: gpio@fd331000 { |
475 | gpio-controller; | 475 | gpio-controller; |
476 | #gpio-cells = <1>; | 476 | #gpio-cells = <1>; |
477 | interrupt-controller; | 477 | interrupt-controller; |
478 | #interrupt-cells = <2>; | 478 | #interrupt-cells = <2>; |
479 | reg = <0x1000 0x100>; | 479 | reg = <0x1000 0x100>; |
480 | st,bank-name = "PIO104"; | 480 | st,bank-name = "PIO104"; |
481 | }; | 481 | }; |
482 | PIO105: gpio@fd332000 { | 482 | PIO105: gpio@fd332000 { |
483 | gpio-controller; | 483 | gpio-controller; |
484 | #gpio-cells = <1>; | 484 | #gpio-cells = <1>; |
485 | interrupt-controller; | 485 | interrupt-controller; |
486 | #interrupt-cells = <2>; | 486 | #interrupt-cells = <2>; |
487 | reg = <0x2000 0x100>; | 487 | reg = <0x2000 0x100>; |
488 | st,bank-name = "PIO105"; | 488 | st,bank-name = "PIO105"; |
489 | }; | 489 | }; |
490 | PIO106: gpio@fd333000 { | 490 | PIO106: gpio@fd333000 { |
491 | gpio-controller; | 491 | gpio-controller; |
492 | #gpio-cells = <1>; | 492 | #gpio-cells = <1>; |
493 | interrupt-controller; | 493 | interrupt-controller; |
494 | #interrupt-cells = <2>; | 494 | #interrupt-cells = <2>; |
495 | reg = <0x3000 0x100>; | 495 | reg = <0x3000 0x100>; |
496 | st,bank-name = "PIO106"; | 496 | st,bank-name = "PIO106"; |
497 | }; | 497 | }; |
498 | PIO107: gpio@fd334000 { | 498 | PIO107: gpio@fd334000 { |
499 | gpio-controller; | 499 | gpio-controller; |
500 | #gpio-cells = <1>; | 500 | #gpio-cells = <1>; |
501 | interrupt-controller; | 501 | interrupt-controller; |
502 | #interrupt-cells = <2>; | 502 | #interrupt-cells = <2>; |
503 | reg = <0x4000 0x100>; | 503 | reg = <0x4000 0x100>; |
504 | st,bank-name = "PIO107"; | 504 | st,bank-name = "PIO107"; |
505 | }; | 505 | }; |
506 | }; | 506 | }; |
507 | }; | 507 | }; |
508 | }; | 508 | }; |
509 | 509 |
arch/arm/boot/dts/stih416-pinctrl.dtsi
1 | 1 | ||
2 | /* | 2 | /* |
3 | * Copyright (C) 2013 STMicroelectronics Limited. | 3 | * Copyright (C) 2013 STMicroelectronics Limited. |
4 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | 4 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * publishhed by the Free Software Foundation. | 8 | * publishhed by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include "st-pincfg.h" | 10 | #include "st-pincfg.h" |
11 | #include <dt-bindings/interrupt-controller/arm-gic.h> | 11 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
12 | / { | 12 | / { |
13 | 13 | ||
14 | aliases { | 14 | aliases { |
15 | gpio0 = &PIO0; | 15 | gpio0 = &PIO0; |
16 | gpio1 = &PIO1; | 16 | gpio1 = &PIO1; |
17 | gpio2 = &PIO2; | 17 | gpio2 = &PIO2; |
18 | gpio3 = &PIO3; | 18 | gpio3 = &PIO3; |
19 | gpio4 = &PIO4; | 19 | gpio4 = &PIO4; |
20 | gpio5 = &PIO40; | 20 | gpio5 = &PIO40; |
21 | gpio6 = &PIO5; | 21 | gpio6 = &PIO5; |
22 | gpio7 = &PIO6; | 22 | gpio7 = &PIO6; |
23 | gpio8 = &PIO7; | 23 | gpio8 = &PIO7; |
24 | gpio9 = &PIO8; | 24 | gpio9 = &PIO8; |
25 | gpio10 = &PIO9; | 25 | gpio10 = &PIO9; |
26 | gpio11 = &PIO10; | 26 | gpio11 = &PIO10; |
27 | gpio12 = &PIO11; | 27 | gpio12 = &PIO11; |
28 | gpio13 = &PIO12; | 28 | gpio13 = &PIO12; |
29 | gpio14 = &PIO30; | 29 | gpio14 = &PIO30; |
30 | gpio15 = &PIO31; | 30 | gpio15 = &PIO31; |
31 | gpio16 = &PIO13; | 31 | gpio16 = &PIO13; |
32 | gpio17 = &PIO14; | 32 | gpio17 = &PIO14; |
33 | gpio18 = &PIO15; | 33 | gpio18 = &PIO15; |
34 | gpio19 = &PIO16; | 34 | gpio19 = &PIO16; |
35 | gpio20 = &PIO17; | 35 | gpio20 = &PIO17; |
36 | gpio21 = &PIO18; | 36 | gpio21 = &PIO18; |
37 | gpio22 = &PIO100; | 37 | gpio22 = &PIO100; |
38 | gpio23 = &PIO101; | 38 | gpio23 = &PIO101; |
39 | gpio24 = &PIO102; | 39 | gpio24 = &PIO102; |
40 | gpio25 = &PIO103; | 40 | gpio25 = &PIO103; |
41 | gpio26 = &PIO104; | 41 | gpio26 = &PIO104; |
42 | gpio27 = &PIO105; | 42 | gpio27 = &PIO105; |
43 | gpio28 = &PIO106; | 43 | gpio28 = &PIO106; |
44 | gpio29 = &PIO107; | 44 | gpio29 = &PIO107; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | soc { | 47 | soc { |
48 | pin-controller-sbc { | 48 | pin-controller-sbc { |
49 | #address-cells = <1>; | 49 | #address-cells = <1>; |
50 | #size-cells = <1>; | 50 | #size-cells = <1>; |
51 | compatible = "st,stih416-sbc-pinctrl"; | 51 | compatible = "st,stih416-sbc-pinctrl"; |
52 | st,syscfg = <&syscfg_sbc>; | 52 | st,syscfg = <&syscfg_sbc>; |
53 | reg = <0xfe61f080 0x4>; | 53 | reg = <0xfe61f080 0x4>; |
54 | reg-names = "irqmux"; | 54 | reg-names = "irqmux"; |
55 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; | 55 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; |
56 | interrupts-names = "irqmux"; | 56 | interrupt-names = "irqmux"; |
57 | ranges = <0 0xfe610000 0x6000>; | 57 | ranges = <0 0xfe610000 0x6000>; |
58 | 58 | ||
59 | PIO0: gpio@fe610000 { | 59 | PIO0: gpio@fe610000 { |
60 | gpio-controller; | 60 | gpio-controller; |
61 | #gpio-cells = <1>; | 61 | #gpio-cells = <1>; |
62 | interrupt-controller; | 62 | interrupt-controller; |
63 | #interrupt-cells = <2>; | 63 | #interrupt-cells = <2>; |
64 | reg = <0 0x100>; | 64 | reg = <0 0x100>; |
65 | st,bank-name = "PIO0"; | 65 | st,bank-name = "PIO0"; |
66 | }; | 66 | }; |
67 | PIO1: gpio@fe611000 { | 67 | PIO1: gpio@fe611000 { |
68 | gpio-controller; | 68 | gpio-controller; |
69 | #gpio-cells = <1>; | 69 | #gpio-cells = <1>; |
70 | interrupt-controller; | 70 | interrupt-controller; |
71 | #interrupt-cells = <2>; | 71 | #interrupt-cells = <2>; |
72 | reg = <0x1000 0x100>; | 72 | reg = <0x1000 0x100>; |
73 | st,bank-name = "PIO1"; | 73 | st,bank-name = "PIO1"; |
74 | }; | 74 | }; |
75 | PIO2: gpio@fe612000 { | 75 | PIO2: gpio@fe612000 { |
76 | gpio-controller; | 76 | gpio-controller; |
77 | #gpio-cells = <1>; | 77 | #gpio-cells = <1>; |
78 | interrupt-controller; | 78 | interrupt-controller; |
79 | #interrupt-cells = <2>; | 79 | #interrupt-cells = <2>; |
80 | reg = <0x2000 0x100>; | 80 | reg = <0x2000 0x100>; |
81 | st,bank-name = "PIO2"; | 81 | st,bank-name = "PIO2"; |
82 | }; | 82 | }; |
83 | PIO3: gpio@fe613000 { | 83 | PIO3: gpio@fe613000 { |
84 | gpio-controller; | 84 | gpio-controller; |
85 | #gpio-cells = <1>; | 85 | #gpio-cells = <1>; |
86 | interrupt-controller; | 86 | interrupt-controller; |
87 | #interrupt-cells = <2>; | 87 | #interrupt-cells = <2>; |
88 | reg = <0x3000 0x100>; | 88 | reg = <0x3000 0x100>; |
89 | st,bank-name = "PIO3"; | 89 | st,bank-name = "PIO3"; |
90 | }; | 90 | }; |
91 | PIO4: gpio@fe614000 { | 91 | PIO4: gpio@fe614000 { |
92 | gpio-controller; | 92 | gpio-controller; |
93 | #gpio-cells = <1>; | 93 | #gpio-cells = <1>; |
94 | interrupt-controller; | 94 | interrupt-controller; |
95 | #interrupt-cells = <2>; | 95 | #interrupt-cells = <2>; |
96 | reg = <0x4000 0x100>; | 96 | reg = <0x4000 0x100>; |
97 | st,bank-name = "PIO4"; | 97 | st,bank-name = "PIO4"; |
98 | }; | 98 | }; |
99 | PIO40: gpio@fe615000 { | 99 | PIO40: gpio@fe615000 { |
100 | gpio-controller; | 100 | gpio-controller; |
101 | #gpio-cells = <1>; | 101 | #gpio-cells = <1>; |
102 | interrupt-controller; | 102 | interrupt-controller; |
103 | #interrupt-cells = <2>; | 103 | #interrupt-cells = <2>; |
104 | reg = <0x5000 0x100>; | 104 | reg = <0x5000 0x100>; |
105 | st,bank-name = "PIO40"; | 105 | st,bank-name = "PIO40"; |
106 | st,retime-pin-mask = <0x7f>; | 106 | st,retime-pin-mask = <0x7f>; |
107 | }; | 107 | }; |
108 | 108 | ||
109 | rc{ | 109 | rc{ |
110 | pinctrl_ir: ir0 { | 110 | pinctrl_ir: ir0 { |
111 | st,pins { | 111 | st,pins { |
112 | ir = <&PIO4 0 ALT2 IN>; | 112 | ir = <&PIO4 0 ALT2 IN>; |
113 | }; | 113 | }; |
114 | }; | 114 | }; |
115 | }; | 115 | }; |
116 | sbc_serial1 { | 116 | sbc_serial1 { |
117 | pinctrl_sbc_serial1: sbc_serial1 { | 117 | pinctrl_sbc_serial1: sbc_serial1 { |
118 | st,pins { | 118 | st,pins { |
119 | tx = <&PIO2 6 ALT3 OUT>; | 119 | tx = <&PIO2 6 ALT3 OUT>; |
120 | rx = <&PIO2 7 ALT3 IN>; | 120 | rx = <&PIO2 7 ALT3 IN>; |
121 | }; | 121 | }; |
122 | }; | 122 | }; |
123 | }; | 123 | }; |
124 | 124 | ||
125 | sbc_i2c0 { | 125 | sbc_i2c0 { |
126 | pinctrl_sbc_i2c0_default: sbc_i2c0-default { | 126 | pinctrl_sbc_i2c0_default: sbc_i2c0-default { |
127 | st,pins { | 127 | st,pins { |
128 | sda = <&PIO4 6 ALT1 BIDIR>; | 128 | sda = <&PIO4 6 ALT1 BIDIR>; |
129 | scl = <&PIO4 5 ALT1 BIDIR>; | 129 | scl = <&PIO4 5 ALT1 BIDIR>; |
130 | }; | 130 | }; |
131 | }; | 131 | }; |
132 | }; | 132 | }; |
133 | 133 | ||
134 | sbc_i2c1 { | 134 | sbc_i2c1 { |
135 | pinctrl_sbc_i2c1_default: sbc_i2c1-default { | 135 | pinctrl_sbc_i2c1_default: sbc_i2c1-default { |
136 | st,pins { | 136 | st,pins { |
137 | sda = <&PIO3 2 ALT2 BIDIR>; | 137 | sda = <&PIO3 2 ALT2 BIDIR>; |
138 | scl = <&PIO3 1 ALT2 BIDIR>; | 138 | scl = <&PIO3 1 ALT2 BIDIR>; |
139 | }; | 139 | }; |
140 | }; | 140 | }; |
141 | }; | 141 | }; |
142 | 142 | ||
143 | gmac1 { | 143 | gmac1 { |
144 | pinctrl_mii1: mii1 { | 144 | pinctrl_mii1: mii1 { |
145 | st,pins { | 145 | st,pins { |
146 | txd0 = <&PIO0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 146 | txd0 = <&PIO0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
147 | txd1 = <&PIO0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 147 | txd1 = <&PIO0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
148 | txd2 = <&PIO0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 148 | txd2 = <&PIO0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
149 | txd3 = <&PIO0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 149 | txd3 = <&PIO0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
150 | txer = <&PIO0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 150 | txer = <&PIO0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
151 | txen = <&PIO0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>; | 151 | txen = <&PIO0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>; |
152 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; | 152 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; |
153 | col = <&PIO0 7 ALT1 IN BYPASS 1000>; | 153 | col = <&PIO0 7 ALT1 IN BYPASS 1000>; |
154 | 154 | ||
155 | mdio = <&PIO1 0 ALT1 OUT BYPASS 1500>; | 155 | mdio = <&PIO1 0 ALT1 OUT BYPASS 1500>; |
156 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; | 156 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; |
157 | crs = <&PIO1 2 ALT1 IN BYPASS 1000>; | 157 | crs = <&PIO1 2 ALT1 IN BYPASS 1000>; |
158 | mdint = <&PIO1 3 ALT1 IN BYPASS 0>; | 158 | mdint = <&PIO1 3 ALT1 IN BYPASS 0>; |
159 | rxd0 = <&PIO1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 159 | rxd0 = <&PIO1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
160 | rxd1 = <&PIO1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 160 | rxd1 = <&PIO1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
161 | rxd2 = <&PIO1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 161 | rxd2 = <&PIO1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
162 | rxd3 = <&PIO1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 162 | rxd3 = <&PIO1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
163 | 163 | ||
164 | rxdv = <&PIO2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 164 | rxdv = <&PIO2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
165 | rx_er = <&PIO2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>; | 165 | rx_er = <&PIO2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>; |
166 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; | 166 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; |
167 | phyclk = <&PIO2 3 ALT1 OUT NICLK 0 CLK_A>; | 167 | phyclk = <&PIO2 3 ALT1 OUT NICLK 0 CLK_A>; |
168 | }; | 168 | }; |
169 | }; | 169 | }; |
170 | pinctrl_rgmii1: rgmii1-0 { | 170 | pinctrl_rgmii1: rgmii1-0 { |
171 | st,pins { | 171 | st,pins { |
172 | txd0 = <&PIO0 0 ALT1 OUT DE_IO 500 CLK_A>; | 172 | txd0 = <&PIO0 0 ALT1 OUT DE_IO 500 CLK_A>; |
173 | txd1 = <&PIO0 1 ALT1 OUT DE_IO 500 CLK_A>; | 173 | txd1 = <&PIO0 1 ALT1 OUT DE_IO 500 CLK_A>; |
174 | txd2 = <&PIO0 2 ALT1 OUT DE_IO 500 CLK_A>; | 174 | txd2 = <&PIO0 2 ALT1 OUT DE_IO 500 CLK_A>; |
175 | txd3 = <&PIO0 3 ALT1 OUT DE_IO 500 CLK_A>; | 175 | txd3 = <&PIO0 3 ALT1 OUT DE_IO 500 CLK_A>; |
176 | txen = <&PIO0 5 ALT1 OUT DE_IO 0 CLK_A>; | 176 | txen = <&PIO0 5 ALT1 OUT DE_IO 0 CLK_A>; |
177 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; | 177 | txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>; |
178 | 178 | ||
179 | mdio = <&PIO1 0 ALT1 OUT BYPASS 0>; | 179 | mdio = <&PIO1 0 ALT1 OUT BYPASS 0>; |
180 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; | 180 | mdc = <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>; |
181 | rxd0 = <&PIO1 4 ALT1 IN DE_IO 500 CLK_A>; | 181 | rxd0 = <&PIO1 4 ALT1 IN DE_IO 500 CLK_A>; |
182 | rxd1 = <&PIO1 5 ALT1 IN DE_IO 500 CLK_A>; | 182 | rxd1 = <&PIO1 5 ALT1 IN DE_IO 500 CLK_A>; |
183 | rxd2 = <&PIO1 6 ALT1 IN DE_IO 500 CLK_A>; | 183 | rxd2 = <&PIO1 6 ALT1 IN DE_IO 500 CLK_A>; |
184 | rxd3 = <&PIO1 7 ALT1 IN DE_IO 500 CLK_A>; | 184 | rxd3 = <&PIO1 7 ALT1 IN DE_IO 500 CLK_A>; |
185 | 185 | ||
186 | rxdv = <&PIO2 0 ALT1 IN DE_IO 500 CLK_A>; | 186 | rxdv = <&PIO2 0 ALT1 IN DE_IO 500 CLK_A>; |
187 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; | 187 | rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>; |
188 | phyclk = <&PIO2 3 ALT4 OUT NICLK 0 CLK_B>; | 188 | phyclk = <&PIO2 3 ALT4 OUT NICLK 0 CLK_B>; |
189 | 189 | ||
190 | clk125= <&PIO3 7 ALT4 IN NICLK 0 CLK_A>; | 190 | clk125= <&PIO3 7 ALT4 IN NICLK 0 CLK_A>; |
191 | }; | 191 | }; |
192 | }; | 192 | }; |
193 | }; | 193 | }; |
194 | }; | 194 | }; |
195 | 195 | ||
196 | pin-controller-front { | 196 | pin-controller-front { |
197 | #address-cells = <1>; | 197 | #address-cells = <1>; |
198 | #size-cells = <1>; | 198 | #size-cells = <1>; |
199 | compatible = "st,stih416-front-pinctrl"; | 199 | compatible = "st,stih416-front-pinctrl"; |
200 | st,syscfg = <&syscfg_front>; | 200 | st,syscfg = <&syscfg_front>; |
201 | reg = <0xfee0f080 0x4>; | 201 | reg = <0xfee0f080 0x4>; |
202 | reg-names = "irqmux"; | 202 | reg-names = "irqmux"; |
203 | interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>; | 203 | interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>; |
204 | interrupts-names = "irqmux"; | 204 | interrupt-names = "irqmux"; |
205 | ranges = <0 0xfee00000 0x10000>; | 205 | ranges = <0 0xfee00000 0x10000>; |
206 | 206 | ||
207 | PIO5: gpio@fee00000 { | 207 | PIO5: gpio@fee00000 { |
208 | gpio-controller; | 208 | gpio-controller; |
209 | #gpio-cells = <1>; | 209 | #gpio-cells = <1>; |
210 | interrupt-controller; | 210 | interrupt-controller; |
211 | #interrupt-cells = <2>; | 211 | #interrupt-cells = <2>; |
212 | reg = <0 0x100>; | 212 | reg = <0 0x100>; |
213 | st,bank-name = "PIO5"; | 213 | st,bank-name = "PIO5"; |
214 | }; | 214 | }; |
215 | PIO6: gpio@fee01000 { | 215 | PIO6: gpio@fee01000 { |
216 | gpio-controller; | 216 | gpio-controller; |
217 | #gpio-cells = <1>; | 217 | #gpio-cells = <1>; |
218 | interrupt-controller; | 218 | interrupt-controller; |
219 | #interrupt-cells = <2>; | 219 | #interrupt-cells = <2>; |
220 | reg = <0x1000 0x100>; | 220 | reg = <0x1000 0x100>; |
221 | st,bank-name = "PIO6"; | 221 | st,bank-name = "PIO6"; |
222 | }; | 222 | }; |
223 | PIO7: gpio@fee02000 { | 223 | PIO7: gpio@fee02000 { |
224 | gpio-controller; | 224 | gpio-controller; |
225 | #gpio-cells = <1>; | 225 | #gpio-cells = <1>; |
226 | interrupt-controller; | 226 | interrupt-controller; |
227 | #interrupt-cells = <2>; | 227 | #interrupt-cells = <2>; |
228 | reg = <0x2000 0x100>; | 228 | reg = <0x2000 0x100>; |
229 | st,bank-name = "PIO7"; | 229 | st,bank-name = "PIO7"; |
230 | }; | 230 | }; |
231 | PIO8: gpio@fee03000 { | 231 | PIO8: gpio@fee03000 { |
232 | gpio-controller; | 232 | gpio-controller; |
233 | #gpio-cells = <1>; | 233 | #gpio-cells = <1>; |
234 | interrupt-controller; | 234 | interrupt-controller; |
235 | #interrupt-cells = <2>; | 235 | #interrupt-cells = <2>; |
236 | reg = <0x3000 0x100>; | 236 | reg = <0x3000 0x100>; |
237 | st,bank-name = "PIO8"; | 237 | st,bank-name = "PIO8"; |
238 | }; | 238 | }; |
239 | PIO9: gpio@fee04000 { | 239 | PIO9: gpio@fee04000 { |
240 | gpio-controller; | 240 | gpio-controller; |
241 | #gpio-cells = <1>; | 241 | #gpio-cells = <1>; |
242 | interrupt-controller; | 242 | interrupt-controller; |
243 | #interrupt-cells = <2>; | 243 | #interrupt-cells = <2>; |
244 | reg = <0x4000 0x100>; | 244 | reg = <0x4000 0x100>; |
245 | st,bank-name = "PIO9"; | 245 | st,bank-name = "PIO9"; |
246 | }; | 246 | }; |
247 | PIO10: gpio@fee05000 { | 247 | PIO10: gpio@fee05000 { |
248 | gpio-controller; | 248 | gpio-controller; |
249 | #gpio-cells = <1>; | 249 | #gpio-cells = <1>; |
250 | interrupt-controller; | 250 | interrupt-controller; |
251 | #interrupt-cells = <2>; | 251 | #interrupt-cells = <2>; |
252 | reg = <0x5000 0x100>; | 252 | reg = <0x5000 0x100>; |
253 | st,bank-name = "PIO10"; | 253 | st,bank-name = "PIO10"; |
254 | }; | 254 | }; |
255 | PIO11: gpio@fee06000 { | 255 | PIO11: gpio@fee06000 { |
256 | gpio-controller; | 256 | gpio-controller; |
257 | #gpio-cells = <1>; | 257 | #gpio-cells = <1>; |
258 | interrupt-controller; | 258 | interrupt-controller; |
259 | #interrupt-cells = <2>; | 259 | #interrupt-cells = <2>; |
260 | reg = <0x6000 0x100>; | 260 | reg = <0x6000 0x100>; |
261 | st,bank-name = "PIO11"; | 261 | st,bank-name = "PIO11"; |
262 | }; | 262 | }; |
263 | PIO12: gpio@fee07000 { | 263 | PIO12: gpio@fee07000 { |
264 | gpio-controller; | 264 | gpio-controller; |
265 | #gpio-cells = <1>; | 265 | #gpio-cells = <1>; |
266 | interrupt-controller; | 266 | interrupt-controller; |
267 | #interrupt-cells = <2>; | 267 | #interrupt-cells = <2>; |
268 | reg = <0x7000 0x100>; | 268 | reg = <0x7000 0x100>; |
269 | st,bank-name = "PIO12"; | 269 | st,bank-name = "PIO12"; |
270 | }; | 270 | }; |
271 | PIO30: gpio@fee08000 { | 271 | PIO30: gpio@fee08000 { |
272 | gpio-controller; | 272 | gpio-controller; |
273 | #gpio-cells = <1>; | 273 | #gpio-cells = <1>; |
274 | interrupt-controller; | 274 | interrupt-controller; |
275 | #interrupt-cells = <2>; | 275 | #interrupt-cells = <2>; |
276 | reg = <0x8000 0x100>; | 276 | reg = <0x8000 0x100>; |
277 | st,bank-name = "PIO30"; | 277 | st,bank-name = "PIO30"; |
278 | }; | 278 | }; |
279 | PIO31: gpio@fee09000 { | 279 | PIO31: gpio@fee09000 { |
280 | gpio-controller; | 280 | gpio-controller; |
281 | #gpio-cells = <1>; | 281 | #gpio-cells = <1>; |
282 | interrupt-controller; | 282 | interrupt-controller; |
283 | #interrupt-cells = <2>; | 283 | #interrupt-cells = <2>; |
284 | reg = <0x9000 0x100>; | 284 | reg = <0x9000 0x100>; |
285 | st,bank-name = "PIO31"; | 285 | st,bank-name = "PIO31"; |
286 | }; | 286 | }; |
287 | 287 | ||
288 | serial2-oe { | 288 | serial2-oe { |
289 | pinctrl_serial2_oe: serial2-1 { | 289 | pinctrl_serial2_oe: serial2-1 { |
290 | st,pins { | 290 | st,pins { |
291 | output-enable = <&PIO11 3 ALT2 OUT>; | 291 | output-enable = <&PIO11 3 ALT2 OUT>; |
292 | }; | 292 | }; |
293 | }; | 293 | }; |
294 | }; | 294 | }; |
295 | 295 | ||
296 | i2c0 { | 296 | i2c0 { |
297 | pinctrl_i2c0_default: i2c0-default { | 297 | pinctrl_i2c0_default: i2c0-default { |
298 | st,pins { | 298 | st,pins { |
299 | sda = <&PIO9 3 ALT1 BIDIR>; | 299 | sda = <&PIO9 3 ALT1 BIDIR>; |
300 | scl = <&PIO9 2 ALT1 BIDIR>; | 300 | scl = <&PIO9 2 ALT1 BIDIR>; |
301 | }; | 301 | }; |
302 | }; | 302 | }; |
303 | }; | 303 | }; |
304 | 304 | ||
305 | i2c1 { | 305 | i2c1 { |
306 | pinctrl_i2c1_default: i2c1-default { | 306 | pinctrl_i2c1_default: i2c1-default { |
307 | st,pins { | 307 | st,pins { |
308 | sda = <&PIO12 1 ALT1 BIDIR>; | 308 | sda = <&PIO12 1 ALT1 BIDIR>; |
309 | scl = <&PIO12 0 ALT1 BIDIR>; | 309 | scl = <&PIO12 0 ALT1 BIDIR>; |
310 | }; | 310 | }; |
311 | }; | 311 | }; |
312 | }; | 312 | }; |
313 | 313 | ||
314 | fsm { | 314 | fsm { |
315 | pinctrl_fsm: fsm { | 315 | pinctrl_fsm: fsm { |
316 | st,pins { | 316 | st,pins { |
317 | spi-fsm-clk = <&PIO12 2 ALT1 OUT>; | 317 | spi-fsm-clk = <&PIO12 2 ALT1 OUT>; |
318 | spi-fsm-cs = <&PIO12 3 ALT1 OUT>; | 318 | spi-fsm-cs = <&PIO12 3 ALT1 OUT>; |
319 | spi-fsm-mosi = <&PIO12 4 ALT1 OUT>; | 319 | spi-fsm-mosi = <&PIO12 4 ALT1 OUT>; |
320 | spi-fsm-miso = <&PIO12 5 ALT1 IN>; | 320 | spi-fsm-miso = <&PIO12 5 ALT1 IN>; |
321 | spi-fsm-hol = <&PIO12 6 ALT1 OUT>; | 321 | spi-fsm-hol = <&PIO12 6 ALT1 OUT>; |
322 | spi-fsm-wp = <&PIO12 7 ALT1 OUT>; | 322 | spi-fsm-wp = <&PIO12 7 ALT1 OUT>; |
323 | }; | 323 | }; |
324 | }; | 324 | }; |
325 | }; | 325 | }; |
326 | }; | 326 | }; |
327 | 327 | ||
328 | pin-controller-rear { | 328 | pin-controller-rear { |
329 | #address-cells = <1>; | 329 | #address-cells = <1>; |
330 | #size-cells = <1>; | 330 | #size-cells = <1>; |
331 | compatible = "st,stih416-rear-pinctrl"; | 331 | compatible = "st,stih416-rear-pinctrl"; |
332 | st,syscfg = <&syscfg_rear>; | 332 | st,syscfg = <&syscfg_rear>; |
333 | reg = <0xfe82f080 0x4>; | 333 | reg = <0xfe82f080 0x4>; |
334 | reg-names = "irqmux"; | 334 | reg-names = "irqmux"; |
335 | interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; | 335 | interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; |
336 | interrupts-names = "irqmux"; | 336 | interrupt-names = "irqmux"; |
337 | ranges = <0 0xfe820000 0x6000>; | 337 | ranges = <0 0xfe820000 0x6000>; |
338 | 338 | ||
339 | PIO13: gpio@fe820000 { | 339 | PIO13: gpio@fe820000 { |
340 | gpio-controller; | 340 | gpio-controller; |
341 | #gpio-cells = <1>; | 341 | #gpio-cells = <1>; |
342 | interrupt-controller; | 342 | interrupt-controller; |
343 | #interrupt-cells = <2>; | 343 | #interrupt-cells = <2>; |
344 | reg = <0 0x100>; | 344 | reg = <0 0x100>; |
345 | st,bank-name = "PIO13"; | 345 | st,bank-name = "PIO13"; |
346 | }; | 346 | }; |
347 | PIO14: gpio@fe821000 { | 347 | PIO14: gpio@fe821000 { |
348 | gpio-controller; | 348 | gpio-controller; |
349 | #gpio-cells = <1>; | 349 | #gpio-cells = <1>; |
350 | interrupt-controller; | 350 | interrupt-controller; |
351 | #interrupt-cells = <2>; | 351 | #interrupt-cells = <2>; |
352 | reg = <0x1000 0x100>; | 352 | reg = <0x1000 0x100>; |
353 | st,bank-name = "PIO14"; | 353 | st,bank-name = "PIO14"; |
354 | }; | 354 | }; |
355 | PIO15: gpio@fe822000 { | 355 | PIO15: gpio@fe822000 { |
356 | gpio-controller; | 356 | gpio-controller; |
357 | #gpio-cells = <1>; | 357 | #gpio-cells = <1>; |
358 | interrupt-controller; | 358 | interrupt-controller; |
359 | #interrupt-cells = <2>; | 359 | #interrupt-cells = <2>; |
360 | reg = <0x2000 0x100>; | 360 | reg = <0x2000 0x100>; |
361 | st,bank-name = "PIO15"; | 361 | st,bank-name = "PIO15"; |
362 | }; | 362 | }; |
363 | PIO16: gpio@fe823000 { | 363 | PIO16: gpio@fe823000 { |
364 | gpio-controller; | 364 | gpio-controller; |
365 | #gpio-cells = <1>; | 365 | #gpio-cells = <1>; |
366 | interrupt-controller; | 366 | interrupt-controller; |
367 | #interrupt-cells = <2>; | 367 | #interrupt-cells = <2>; |
368 | reg = <0x3000 0x100>; | 368 | reg = <0x3000 0x100>; |
369 | st,bank-name = "PIO16"; | 369 | st,bank-name = "PIO16"; |
370 | }; | 370 | }; |
371 | PIO17: gpio@fe824000 { | 371 | PIO17: gpio@fe824000 { |
372 | gpio-controller; | 372 | gpio-controller; |
373 | #gpio-cells = <1>; | 373 | #gpio-cells = <1>; |
374 | interrupt-controller; | 374 | interrupt-controller; |
375 | #interrupt-cells = <2>; | 375 | #interrupt-cells = <2>; |
376 | reg = <0x4000 0x100>; | 376 | reg = <0x4000 0x100>; |
377 | st,bank-name = "PIO17"; | 377 | st,bank-name = "PIO17"; |
378 | }; | 378 | }; |
379 | PIO18: gpio@fe825000 { | 379 | PIO18: gpio@fe825000 { |
380 | gpio-controller; | 380 | gpio-controller; |
381 | #gpio-cells = <1>; | 381 | #gpio-cells = <1>; |
382 | interrupt-controller; | 382 | interrupt-controller; |
383 | #interrupt-cells = <2>; | 383 | #interrupt-cells = <2>; |
384 | reg = <0x5000 0x100>; | 384 | reg = <0x5000 0x100>; |
385 | st,bank-name = "PIO18"; | 385 | st,bank-name = "PIO18"; |
386 | st,retime-pin-mask = <0xf>; | 386 | st,retime-pin-mask = <0xf>; |
387 | }; | 387 | }; |
388 | 388 | ||
389 | serial2 { | 389 | serial2 { |
390 | pinctrl_serial2: serial2-0 { | 390 | pinctrl_serial2: serial2-0 { |
391 | st,pins { | 391 | st,pins { |
392 | tx = <&PIO17 4 ALT2 OUT>; | 392 | tx = <&PIO17 4 ALT2 OUT>; |
393 | rx = <&PIO17 5 ALT2 IN>; | 393 | rx = <&PIO17 5 ALT2 IN>; |
394 | }; | 394 | }; |
395 | }; | 395 | }; |
396 | }; | 396 | }; |
397 | 397 | ||
398 | gmac0 { | 398 | gmac0 { |
399 | pinctrl_mii0: mii0 { | 399 | pinctrl_mii0: mii0 { |
400 | st,pins { | 400 | st,pins { |
401 | mdint = <&PIO13 6 ALT2 IN BYPASS 0>; | 401 | mdint = <&PIO13 6 ALT2 IN BYPASS 0>; |
402 | txen = <&PIO13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 402 | txen = <&PIO13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
403 | txd0 = <&PIO14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 403 | txd0 = <&PIO14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
404 | txd1 = <&PIO14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 404 | txd1 = <&PIO14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
405 | txd2 = <&PIO14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>; | 405 | txd2 = <&PIO14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>; |
406 | txd3 = <&PIO14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>; | 406 | txd3 = <&PIO14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>; |
407 | 407 | ||
408 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; | 408 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; |
409 | txer = <&PIO15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; | 409 | txer = <&PIO15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>; |
410 | crs = <&PIO15 2 ALT2 IN BYPASS 1000>; | 410 | crs = <&PIO15 2 ALT2 IN BYPASS 1000>; |
411 | col = <&PIO15 3 ALT2 IN BYPASS 1000>; | 411 | col = <&PIO15 3 ALT2 IN BYPASS 1000>; |
412 | mdio= <&PIO15 4 ALT2 OUT BYPASS 1500>; | 412 | mdio= <&PIO15 4 ALT2 OUT BYPASS 1500>; |
413 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; | 413 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; |
414 | 414 | ||
415 | rxd0 = <&PIO16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 415 | rxd0 = <&PIO16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
416 | rxd1 = <&PIO16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 416 | rxd1 = <&PIO16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
417 | rxd2 = <&PIO16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 417 | rxd2 = <&PIO16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
418 | rxd3 = <&PIO16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 418 | rxd3 = <&PIO16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
419 | rxdv = <&PIO15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 419 | rxdv = <&PIO15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
420 | rx_er = <&PIO15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>; | 420 | rx_er = <&PIO15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>; |
421 | rxclk = <&PIO17 0 ALT2 IN NICLK 0 CLK_A>; | 421 | rxclk = <&PIO17 0 ALT2 IN NICLK 0 CLK_A>; |
422 | phyclk = <&PIO13 5 ALT2 OUT NICLK 0 CLK_B>; | 422 | phyclk = <&PIO13 5 ALT2 OUT NICLK 0 CLK_B>; |
423 | }; | 423 | }; |
424 | }; | 424 | }; |
425 | 425 | ||
426 | pinctrl_gmii0: gmii0 { | 426 | pinctrl_gmii0: gmii0 { |
427 | st,pins { | 427 | st,pins { |
428 | }; | 428 | }; |
429 | }; | 429 | }; |
430 | pinctrl_rgmii0: rgmii0 { | 430 | pinctrl_rgmii0: rgmii0 { |
431 | st,pins { | 431 | st,pins { |
432 | phyclk = <&PIO13 5 ALT4 OUT NICLK 0 CLK_B>; | 432 | phyclk = <&PIO13 5 ALT4 OUT NICLK 0 CLK_B>; |
433 | txen = <&PIO13 7 ALT2 OUT DE_IO 0 CLK_A>; | 433 | txen = <&PIO13 7 ALT2 OUT DE_IO 0 CLK_A>; |
434 | txd0 = <&PIO14 0 ALT2 OUT DE_IO 500 CLK_A>; | 434 | txd0 = <&PIO14 0 ALT2 OUT DE_IO 500 CLK_A>; |
435 | txd1 = <&PIO14 1 ALT2 OUT DE_IO 500 CLK_A>; | 435 | txd1 = <&PIO14 1 ALT2 OUT DE_IO 500 CLK_A>; |
436 | txd2 = <&PIO14 2 ALT2 OUT DE_IO 500 CLK_B>; | 436 | txd2 = <&PIO14 2 ALT2 OUT DE_IO 500 CLK_B>; |
437 | txd3 = <&PIO14 3 ALT2 OUT DE_IO 500 CLK_B>; | 437 | txd3 = <&PIO14 3 ALT2 OUT DE_IO 500 CLK_B>; |
438 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; | 438 | txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>; |
439 | 439 | ||
440 | mdio = <&PIO15 4 ALT2 OUT BYPASS 0>; | 440 | mdio = <&PIO15 4 ALT2 OUT BYPASS 0>; |
441 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; | 441 | mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>; |
442 | 442 | ||
443 | rxdv = <&PIO15 6 ALT2 IN DE_IO 500 CLK_A>; | 443 | rxdv = <&PIO15 6 ALT2 IN DE_IO 500 CLK_A>; |
444 | rxd0 =<&PIO16 0 ALT2 IN DE_IO 500 CLK_A>; | 444 | rxd0 =<&PIO16 0 ALT2 IN DE_IO 500 CLK_A>; |
445 | rxd1 =<&PIO16 1 ALT2 IN DE_IO 500 CLK_A>; | 445 | rxd1 =<&PIO16 1 ALT2 IN DE_IO 500 CLK_A>; |
446 | rxd2 =<&PIO16 2 ALT2 IN DE_IO 500 CLK_A>; | 446 | rxd2 =<&PIO16 2 ALT2 IN DE_IO 500 CLK_A>; |
447 | rxd3 =<&PIO16 3 ALT2 IN DE_IO 500 CLK_A>; | 447 | rxd3 =<&PIO16 3 ALT2 IN DE_IO 500 CLK_A>; |
448 | rxclk =<&PIO17 0 ALT2 IN NICLK 0 CLK_A>; | 448 | rxclk =<&PIO17 0 ALT2 IN NICLK 0 CLK_A>; |
449 | 449 | ||
450 | clk125=<&PIO17 6 ALT1 IN NICLK 0 CLK_A>; | 450 | clk125=<&PIO17 6 ALT1 IN NICLK 0 CLK_A>; |
451 | }; | 451 | }; |
452 | }; | 452 | }; |
453 | }; | 453 | }; |
454 | }; | 454 | }; |
455 | 455 | ||
456 | pin-controller-fvdp-fe { | 456 | pin-controller-fvdp-fe { |
457 | #address-cells = <1>; | 457 | #address-cells = <1>; |
458 | #size-cells = <1>; | 458 | #size-cells = <1>; |
459 | compatible = "st,stih416-fvdp-fe-pinctrl"; | 459 | compatible = "st,stih416-fvdp-fe-pinctrl"; |
460 | st,syscfg = <&syscfg_fvdp_fe>; | 460 | st,syscfg = <&syscfg_fvdp_fe>; |
461 | reg = <0xfd6bf080 0x4>; | 461 | reg = <0xfd6bf080 0x4>; |
462 | reg-names = "irqmux"; | 462 | reg-names = "irqmux"; |
463 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; | 463 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; |
464 | interrupts-names = "irqmux"; | 464 | interrupt-names = "irqmux"; |
465 | ranges = <0 0xfd6b0000 0x3000>; | 465 | ranges = <0 0xfd6b0000 0x3000>; |
466 | 466 | ||
467 | PIO100: gpio@fd6b0000 { | 467 | PIO100: gpio@fd6b0000 { |
468 | gpio-controller; | 468 | gpio-controller; |
469 | #gpio-cells = <1>; | 469 | #gpio-cells = <1>; |
470 | interrupt-controller; | 470 | interrupt-controller; |
471 | #interrupt-cells = <2>; | 471 | #interrupt-cells = <2>; |
472 | reg = <0 0x100>; | 472 | reg = <0 0x100>; |
473 | st,bank-name = "PIO100"; | 473 | st,bank-name = "PIO100"; |
474 | }; | 474 | }; |
475 | PIO101: gpio@fd6b1000 { | 475 | PIO101: gpio@fd6b1000 { |
476 | gpio-controller; | 476 | gpio-controller; |
477 | #gpio-cells = <1>; | 477 | #gpio-cells = <1>; |
478 | interrupt-controller; | 478 | interrupt-controller; |
479 | #interrupt-cells = <2>; | 479 | #interrupt-cells = <2>; |
480 | reg = <0x1000 0x100>; | 480 | reg = <0x1000 0x100>; |
481 | st,bank-name = "PIO101"; | 481 | st,bank-name = "PIO101"; |
482 | }; | 482 | }; |
483 | PIO102: gpio@fd6b2000 { | 483 | PIO102: gpio@fd6b2000 { |
484 | gpio-controller; | 484 | gpio-controller; |
485 | #gpio-cells = <1>; | 485 | #gpio-cells = <1>; |
486 | interrupt-controller; | 486 | interrupt-controller; |
487 | #interrupt-cells = <2>; | 487 | #interrupt-cells = <2>; |
488 | reg = <0x2000 0x100>; | 488 | reg = <0x2000 0x100>; |
489 | st,bank-name = "PIO102"; | 489 | st,bank-name = "PIO102"; |
490 | }; | 490 | }; |
491 | }; | 491 | }; |
492 | 492 | ||
493 | pin-controller-fvdp-lite { | 493 | pin-controller-fvdp-lite { |
494 | #address-cells = <1>; | 494 | #address-cells = <1>; |
495 | #size-cells = <1>; | 495 | #size-cells = <1>; |
496 | compatible = "st,stih416-fvdp-lite-pinctrl"; | 496 | compatible = "st,stih416-fvdp-lite-pinctrl"; |
497 | st,syscfg = <&syscfg_fvdp_lite>; | 497 | st,syscfg = <&syscfg_fvdp_lite>; |
498 | reg = <0xfd33f080 0x4>; | 498 | reg = <0xfd33f080 0x4>; |
499 | reg-names = "irqmux"; | 499 | reg-names = "irqmux"; |
500 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; | 500 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; |
501 | interrupts-names = "irqmux"; | 501 | interrupt-names = "irqmux"; |
502 | ranges = <0 0xfd330000 0x5000>; | 502 | ranges = <0 0xfd330000 0x5000>; |
503 | 503 | ||
504 | PIO103: gpio@fd330000 { | 504 | PIO103: gpio@fd330000 { |
505 | gpio-controller; | 505 | gpio-controller; |
506 | #gpio-cells = <1>; | 506 | #gpio-cells = <1>; |
507 | interrupt-controller; | 507 | interrupt-controller; |
508 | #interrupt-cells = <2>; | 508 | #interrupt-cells = <2>; |
509 | reg = <0 0x100>; | 509 | reg = <0 0x100>; |
510 | st,bank-name = "PIO103"; | 510 | st,bank-name = "PIO103"; |
511 | }; | 511 | }; |
512 | PIO104: gpio@fd331000 { | 512 | PIO104: gpio@fd331000 { |
513 | gpio-controller; | 513 | gpio-controller; |
514 | #gpio-cells = <1>; | 514 | #gpio-cells = <1>; |
515 | interrupt-controller; | 515 | interrupt-controller; |
516 | #interrupt-cells = <2>; | 516 | #interrupt-cells = <2>; |
517 | reg = <0x1000 0x100>; | 517 | reg = <0x1000 0x100>; |
518 | st,bank-name = "PIO104"; | 518 | st,bank-name = "PIO104"; |
519 | }; | 519 | }; |
520 | PIO105: gpio@fd332000 { | 520 | PIO105: gpio@fd332000 { |
521 | gpio-controller; | 521 | gpio-controller; |
522 | #gpio-cells = <1>; | 522 | #gpio-cells = <1>; |
523 | interrupt-controller; | 523 | interrupt-controller; |
524 | #interrupt-cells = <2>; | 524 | #interrupt-cells = <2>; |
525 | reg = <0x2000 0x100>; | 525 | reg = <0x2000 0x100>; |
526 | st,bank-name = "PIO105"; | 526 | st,bank-name = "PIO105"; |
527 | }; | 527 | }; |
528 | PIO106: gpio@fd333000 { | 528 | PIO106: gpio@fd333000 { |
529 | gpio-controller; | 529 | gpio-controller; |
530 | #gpio-cells = <1>; | 530 | #gpio-cells = <1>; |
531 | interrupt-controller; | 531 | interrupt-controller; |
532 | #interrupt-cells = <2>; | 532 | #interrupt-cells = <2>; |
533 | reg = <0x3000 0x100>; | 533 | reg = <0x3000 0x100>; |
534 | st,bank-name = "PIO106"; | 534 | st,bank-name = "PIO106"; |
535 | }; | 535 | }; |
536 | 536 | ||
537 | PIO107: gpio@fd334000 { | 537 | PIO107: gpio@fd334000 { |
538 | gpio-controller; | 538 | gpio-controller; |
539 | #gpio-cells = <1>; | 539 | #gpio-cells = <1>; |
540 | interrupt-controller; | 540 | interrupt-controller; |
541 | #interrupt-cells = <2>; | 541 | #interrupt-cells = <2>; |
542 | reg = <0x4000 0x100>; | 542 | reg = <0x4000 0x100>; |
543 | st,bank-name = "PIO107"; | 543 | st,bank-name = "PIO107"; |
544 | st,retime-pin-mask = <0xf>; | 544 | st,retime-pin-mask = <0xf>; |
545 | }; | 545 | }; |
546 | }; | 546 | }; |
547 | }; | 547 | }; |
548 | }; | 548 | }; |
549 | 549 |
drivers/base/platform.c
1 | /* | 1 | /* |
2 | * platform.c - platform 'pseudo' bus for legacy devices | 2 | * platform.c - platform 'pseudo' bus for legacy devices |
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * | 6 | * |
7 | * This file is released under the GPLv2 | 7 | * This file is released under the GPLv2 |
8 | * | 8 | * |
9 | * Please see Documentation/driver-model/platform.txt for more | 9 | * Please see Documentation/driver-model/platform.txt for more |
10 | * information. | 10 | * information. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
16 | #include <linux/of_irq.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
19 | #include <linux/bootmem.h> | 20 | #include <linux/bootmem.h> |
20 | #include <linux/err.h> | 21 | #include <linux/err.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
23 | #include <linux/idr.h> | 24 | #include <linux/idr.h> |
24 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
25 | 26 | ||
26 | #include "base.h" | 27 | #include "base.h" |
27 | #include "power/power.h" | 28 | #include "power/power.h" |
28 | 29 | ||
29 | /* For automatically allocated device IDs */ | 30 | /* For automatically allocated device IDs */ |
30 | static DEFINE_IDA(platform_devid_ida); | 31 | static DEFINE_IDA(platform_devid_ida); |
31 | 32 | ||
32 | struct device platform_bus = { | 33 | struct device platform_bus = { |
33 | .init_name = "platform", | 34 | .init_name = "platform", |
34 | }; | 35 | }; |
35 | EXPORT_SYMBOL_GPL(platform_bus); | 36 | EXPORT_SYMBOL_GPL(platform_bus); |
36 | 37 | ||
37 | /** | 38 | /** |
38 | * arch_setup_pdev_archdata - Allow manipulation of archdata before its used | 39 | * arch_setup_pdev_archdata - Allow manipulation of archdata before its used |
39 | * @pdev: platform device | 40 | * @pdev: platform device |
40 | * | 41 | * |
41 | * This is called before platform_device_add() such that any pdev_archdata may | 42 | * This is called before platform_device_add() such that any pdev_archdata may |
42 | * be setup before the platform_notifier is called. So if a user needs to | 43 | * be setup before the platform_notifier is called. So if a user needs to |
43 | * manipulate any relevant information in the pdev_archdata they can do: | 44 | * manipulate any relevant information in the pdev_archdata they can do: |
44 | * | 45 | * |
45 | * platform_device_alloc() | 46 | * platform_device_alloc() |
46 | * ... manipulate ... | 47 | * ... manipulate ... |
47 | * platform_device_add() | 48 | * platform_device_add() |
48 | * | 49 | * |
49 | * And if they don't care they can just call platform_device_register() and | 50 | * And if they don't care they can just call platform_device_register() and |
50 | * everything will just work out. | 51 | * everything will just work out. |
51 | */ | 52 | */ |
52 | void __weak arch_setup_pdev_archdata(struct platform_device *pdev) | 53 | void __weak arch_setup_pdev_archdata(struct platform_device *pdev) |
53 | { | 54 | { |
54 | } | 55 | } |
55 | 56 | ||
56 | /** | 57 | /** |
57 | * platform_get_resource - get a resource for a device | 58 | * platform_get_resource - get a resource for a device |
58 | * @dev: platform device | 59 | * @dev: platform device |
59 | * @type: resource type | 60 | * @type: resource type |
60 | * @num: resource index | 61 | * @num: resource index |
61 | */ | 62 | */ |
62 | struct resource *platform_get_resource(struct platform_device *dev, | 63 | struct resource *platform_get_resource(struct platform_device *dev, |
63 | unsigned int type, unsigned int num) | 64 | unsigned int type, unsigned int num) |
64 | { | 65 | { |
65 | int i; | 66 | int i; |
66 | 67 | ||
67 | for (i = 0; i < dev->num_resources; i++) { | 68 | for (i = 0; i < dev->num_resources; i++) { |
68 | struct resource *r = &dev->resource[i]; | 69 | struct resource *r = &dev->resource[i]; |
69 | 70 | ||
70 | if (type == resource_type(r) && num-- == 0) | 71 | if (type == resource_type(r) && num-- == 0) |
71 | return r; | 72 | return r; |
72 | } | 73 | } |
73 | return NULL; | 74 | return NULL; |
74 | } | 75 | } |
75 | EXPORT_SYMBOL_GPL(platform_get_resource); | 76 | EXPORT_SYMBOL_GPL(platform_get_resource); |
76 | 77 | ||
77 | /** | 78 | /** |
78 | * platform_get_irq - get an IRQ for a device | 79 | * platform_get_irq - get an IRQ for a device |
79 | * @dev: platform device | 80 | * @dev: platform device |
80 | * @num: IRQ number index | 81 | * @num: IRQ number index |
81 | */ | 82 | */ |
82 | int platform_get_irq(struct platform_device *dev, unsigned int num) | 83 | int platform_get_irq(struct platform_device *dev, unsigned int num) |
83 | { | 84 | { |
84 | #ifdef CONFIG_SPARC | 85 | #ifdef CONFIG_SPARC |
85 | /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ | 86 | /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ |
86 | if (!dev || num >= dev->archdata.num_irqs) | 87 | if (!dev || num >= dev->archdata.num_irqs) |
87 | return -ENXIO; | 88 | return -ENXIO; |
88 | return dev->archdata.irqs[num]; | 89 | return dev->archdata.irqs[num]; |
89 | #else | 90 | #else |
90 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); | 91 | struct resource *r; |
92 | if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) | ||
93 | return of_irq_get(dev->dev.of_node, num); | ||
94 | |||
95 | r = platform_get_resource(dev, IORESOURCE_IRQ, num); | ||
91 | 96 | ||
92 | return r ? r->start : -ENXIO; | 97 | return r ? r->start : -ENXIO; |
93 | #endif | 98 | #endif |
94 | } | 99 | } |
95 | EXPORT_SYMBOL_GPL(platform_get_irq); | 100 | EXPORT_SYMBOL_GPL(platform_get_irq); |
96 | 101 | ||
97 | /** | 102 | /** |
98 | * platform_get_resource_byname - get a resource for a device by name | 103 | * platform_get_resource_byname - get a resource for a device by name |
99 | * @dev: platform device | 104 | * @dev: platform device |
100 | * @type: resource type | 105 | * @type: resource type |
101 | * @name: resource name | 106 | * @name: resource name |
102 | */ | 107 | */ |
103 | struct resource *platform_get_resource_byname(struct platform_device *dev, | 108 | struct resource *platform_get_resource_byname(struct platform_device *dev, |
104 | unsigned int type, | 109 | unsigned int type, |
105 | const char *name) | 110 | const char *name) |
106 | { | 111 | { |
107 | int i; | 112 | int i; |
108 | 113 | ||
109 | for (i = 0; i < dev->num_resources; i++) { | 114 | for (i = 0; i < dev->num_resources; i++) { |
110 | struct resource *r = &dev->resource[i]; | 115 | struct resource *r = &dev->resource[i]; |
111 | 116 | ||
112 | if (unlikely(!r->name)) | 117 | if (unlikely(!r->name)) |
113 | continue; | 118 | continue; |
114 | 119 | ||
115 | if (type == resource_type(r) && !strcmp(r->name, name)) | 120 | if (type == resource_type(r) && !strcmp(r->name, name)) |
116 | return r; | 121 | return r; |
117 | } | 122 | } |
118 | return NULL; | 123 | return NULL; |
119 | } | 124 | } |
120 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); | 125 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); |
121 | 126 | ||
122 | /** | 127 | /** |
123 | * platform_get_irq_byname - get an IRQ for a device by name | 128 | * platform_get_irq_byname - get an IRQ for a device by name |
124 | * @dev: platform device | 129 | * @dev: platform device |
125 | * @name: IRQ name | 130 | * @name: IRQ name |
126 | */ | 131 | */ |
127 | int platform_get_irq_byname(struct platform_device *dev, const char *name) | 132 | int platform_get_irq_byname(struct platform_device *dev, const char *name) |
128 | { | 133 | { |
129 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, | 134 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, |
130 | name); | 135 | name); |
131 | 136 | ||
132 | return r ? r->start : -ENXIO; | 137 | return r ? r->start : -ENXIO; |
133 | } | 138 | } |
134 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); | 139 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); |
135 | 140 | ||
136 | /** | 141 | /** |
137 | * platform_add_devices - add a numbers of platform devices | 142 | * platform_add_devices - add a numbers of platform devices |
138 | * @devs: array of platform devices to add | 143 | * @devs: array of platform devices to add |
139 | * @num: number of platform devices in array | 144 | * @num: number of platform devices in array |
140 | */ | 145 | */ |
141 | int platform_add_devices(struct platform_device **devs, int num) | 146 | int platform_add_devices(struct platform_device **devs, int num) |
142 | { | 147 | { |
143 | int i, ret = 0; | 148 | int i, ret = 0; |
144 | 149 | ||
145 | for (i = 0; i < num; i++) { | 150 | for (i = 0; i < num; i++) { |
146 | ret = platform_device_register(devs[i]); | 151 | ret = platform_device_register(devs[i]); |
147 | if (ret) { | 152 | if (ret) { |
148 | while (--i >= 0) | 153 | while (--i >= 0) |
149 | platform_device_unregister(devs[i]); | 154 | platform_device_unregister(devs[i]); |
150 | break; | 155 | break; |
151 | } | 156 | } |
152 | } | 157 | } |
153 | 158 | ||
154 | return ret; | 159 | return ret; |
155 | } | 160 | } |
156 | EXPORT_SYMBOL_GPL(platform_add_devices); | 161 | EXPORT_SYMBOL_GPL(platform_add_devices); |
157 | 162 | ||
158 | struct platform_object { | 163 | struct platform_object { |
159 | struct platform_device pdev; | 164 | struct platform_device pdev; |
160 | char name[1]; | 165 | char name[1]; |
161 | }; | 166 | }; |
162 | 167 | ||
163 | /** | 168 | /** |
164 | * platform_device_put - destroy a platform device | 169 | * platform_device_put - destroy a platform device |
165 | * @pdev: platform device to free | 170 | * @pdev: platform device to free |
166 | * | 171 | * |
167 | * Free all memory associated with a platform device. This function must | 172 | * Free all memory associated with a platform device. This function must |
168 | * _only_ be externally called in error cases. All other usage is a bug. | 173 | * _only_ be externally called in error cases. All other usage is a bug. |
169 | */ | 174 | */ |
170 | void platform_device_put(struct platform_device *pdev) | 175 | void platform_device_put(struct platform_device *pdev) |
171 | { | 176 | { |
172 | if (pdev) | 177 | if (pdev) |
173 | put_device(&pdev->dev); | 178 | put_device(&pdev->dev); |
174 | } | 179 | } |
175 | EXPORT_SYMBOL_GPL(platform_device_put); | 180 | EXPORT_SYMBOL_GPL(platform_device_put); |
176 | 181 | ||
177 | static void platform_device_release(struct device *dev) | 182 | static void platform_device_release(struct device *dev) |
178 | { | 183 | { |
179 | struct platform_object *pa = container_of(dev, struct platform_object, | 184 | struct platform_object *pa = container_of(dev, struct platform_object, |
180 | pdev.dev); | 185 | pdev.dev); |
181 | 186 | ||
182 | of_device_node_put(&pa->pdev.dev); | 187 | of_device_node_put(&pa->pdev.dev); |
183 | kfree(pa->pdev.dev.platform_data); | 188 | kfree(pa->pdev.dev.platform_data); |
184 | kfree(pa->pdev.mfd_cell); | 189 | kfree(pa->pdev.mfd_cell); |
185 | kfree(pa->pdev.resource); | 190 | kfree(pa->pdev.resource); |
186 | kfree(pa); | 191 | kfree(pa); |
187 | } | 192 | } |
188 | 193 | ||
189 | /** | 194 | /** |
190 | * platform_device_alloc - create a platform device | 195 | * platform_device_alloc - create a platform device |
191 | * @name: base name of the device we're adding | 196 | * @name: base name of the device we're adding |
192 | * @id: instance id | 197 | * @id: instance id |
193 | * | 198 | * |
194 | * Create a platform device object which can have other objects attached | 199 | * Create a platform device object which can have other objects attached |
195 | * to it, and which will have attached objects freed when it is released. | 200 | * to it, and which will have attached objects freed when it is released. |
196 | */ | 201 | */ |
197 | struct platform_device *platform_device_alloc(const char *name, int id) | 202 | struct platform_device *platform_device_alloc(const char *name, int id) |
198 | { | 203 | { |
199 | struct platform_object *pa; | 204 | struct platform_object *pa; |
200 | 205 | ||
201 | pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL); | 206 | pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL); |
202 | if (pa) { | 207 | if (pa) { |
203 | strcpy(pa->name, name); | 208 | strcpy(pa->name, name); |
204 | pa->pdev.name = pa->name; | 209 | pa->pdev.name = pa->name; |
205 | pa->pdev.id = id; | 210 | pa->pdev.id = id; |
206 | device_initialize(&pa->pdev.dev); | 211 | device_initialize(&pa->pdev.dev); |
207 | pa->pdev.dev.release = platform_device_release; | 212 | pa->pdev.dev.release = platform_device_release; |
208 | arch_setup_pdev_archdata(&pa->pdev); | 213 | arch_setup_pdev_archdata(&pa->pdev); |
209 | } | 214 | } |
210 | 215 | ||
211 | return pa ? &pa->pdev : NULL; | 216 | return pa ? &pa->pdev : NULL; |
212 | } | 217 | } |
213 | EXPORT_SYMBOL_GPL(platform_device_alloc); | 218 | EXPORT_SYMBOL_GPL(platform_device_alloc); |
214 | 219 | ||
215 | /** | 220 | /** |
216 | * platform_device_add_resources - add resources to a platform device | 221 | * platform_device_add_resources - add resources to a platform device |
217 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 222 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
218 | * @res: set of resources that needs to be allocated for the device | 223 | * @res: set of resources that needs to be allocated for the device |
219 | * @num: number of resources | 224 | * @num: number of resources |
220 | * | 225 | * |
221 | * Add a copy of the resources to the platform device. The memory | 226 | * Add a copy of the resources to the platform device. The memory |
222 | * associated with the resources will be freed when the platform device is | 227 | * associated with the resources will be freed when the platform device is |
223 | * released. | 228 | * released. |
224 | */ | 229 | */ |
225 | int platform_device_add_resources(struct platform_device *pdev, | 230 | int platform_device_add_resources(struct platform_device *pdev, |
226 | const struct resource *res, unsigned int num) | 231 | const struct resource *res, unsigned int num) |
227 | { | 232 | { |
228 | struct resource *r = NULL; | 233 | struct resource *r = NULL; |
229 | 234 | ||
230 | if (res) { | 235 | if (res) { |
231 | r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); | 236 | r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); |
232 | if (!r) | 237 | if (!r) |
233 | return -ENOMEM; | 238 | return -ENOMEM; |
234 | } | 239 | } |
235 | 240 | ||
236 | kfree(pdev->resource); | 241 | kfree(pdev->resource); |
237 | pdev->resource = r; | 242 | pdev->resource = r; |
238 | pdev->num_resources = num; | 243 | pdev->num_resources = num; |
239 | return 0; | 244 | return 0; |
240 | } | 245 | } |
241 | EXPORT_SYMBOL_GPL(platform_device_add_resources); | 246 | EXPORT_SYMBOL_GPL(platform_device_add_resources); |
242 | 247 | ||
243 | /** | 248 | /** |
244 | * platform_device_add_data - add platform-specific data to a platform device | 249 | * platform_device_add_data - add platform-specific data to a platform device |
245 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 250 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
246 | * @data: platform specific data for this platform device | 251 | * @data: platform specific data for this platform device |
247 | * @size: size of platform specific data | 252 | * @size: size of platform specific data |
248 | * | 253 | * |
249 | * Add a copy of platform specific data to the platform device's | 254 | * Add a copy of platform specific data to the platform device's |
250 | * platform_data pointer. The memory associated with the platform data | 255 | * platform_data pointer. The memory associated with the platform data |
251 | * will be freed when the platform device is released. | 256 | * will be freed when the platform device is released. |
252 | */ | 257 | */ |
253 | int platform_device_add_data(struct platform_device *pdev, const void *data, | 258 | int platform_device_add_data(struct platform_device *pdev, const void *data, |
254 | size_t size) | 259 | size_t size) |
255 | { | 260 | { |
256 | void *d = NULL; | 261 | void *d = NULL; |
257 | 262 | ||
258 | if (data) { | 263 | if (data) { |
259 | d = kmemdup(data, size, GFP_KERNEL); | 264 | d = kmemdup(data, size, GFP_KERNEL); |
260 | if (!d) | 265 | if (!d) |
261 | return -ENOMEM; | 266 | return -ENOMEM; |
262 | } | 267 | } |
263 | 268 | ||
264 | kfree(pdev->dev.platform_data); | 269 | kfree(pdev->dev.platform_data); |
265 | pdev->dev.platform_data = d; | 270 | pdev->dev.platform_data = d; |
266 | return 0; | 271 | return 0; |
267 | } | 272 | } |
268 | EXPORT_SYMBOL_GPL(platform_device_add_data); | 273 | EXPORT_SYMBOL_GPL(platform_device_add_data); |
269 | 274 | ||
270 | /** | 275 | /** |
271 | * platform_device_add - add a platform device to device hierarchy | 276 | * platform_device_add - add a platform device to device hierarchy |
272 | * @pdev: platform device we're adding | 277 | * @pdev: platform device we're adding |
273 | * | 278 | * |
274 | * This is part 2 of platform_device_register(), though may be called | 279 | * This is part 2 of platform_device_register(), though may be called |
275 | * separately _iff_ pdev was allocated by platform_device_alloc(). | 280 | * separately _iff_ pdev was allocated by platform_device_alloc(). |
276 | */ | 281 | */ |
277 | int platform_device_add(struct platform_device *pdev) | 282 | int platform_device_add(struct platform_device *pdev) |
278 | { | 283 | { |
279 | int i, ret; | 284 | int i, ret; |
280 | 285 | ||
281 | if (!pdev) | 286 | if (!pdev) |
282 | return -EINVAL; | 287 | return -EINVAL; |
283 | 288 | ||
284 | if (!pdev->dev.parent) | 289 | if (!pdev->dev.parent) |
285 | pdev->dev.parent = &platform_bus; | 290 | pdev->dev.parent = &platform_bus; |
286 | 291 | ||
287 | pdev->dev.bus = &platform_bus_type; | 292 | pdev->dev.bus = &platform_bus_type; |
288 | 293 | ||
289 | switch (pdev->id) { | 294 | switch (pdev->id) { |
290 | default: | 295 | default: |
291 | dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); | 296 | dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); |
292 | break; | 297 | break; |
293 | case PLATFORM_DEVID_NONE: | 298 | case PLATFORM_DEVID_NONE: |
294 | dev_set_name(&pdev->dev, "%s", pdev->name); | 299 | dev_set_name(&pdev->dev, "%s", pdev->name); |
295 | break; | 300 | break; |
296 | case PLATFORM_DEVID_AUTO: | 301 | case PLATFORM_DEVID_AUTO: |
297 | /* | 302 | /* |
298 | * Automatically allocated device ID. We mark it as such so | 303 | * Automatically allocated device ID. We mark it as such so |
299 | * that we remember it must be freed, and we append a suffix | 304 | * that we remember it must be freed, and we append a suffix |
300 | * to avoid namespace collision with explicit IDs. | 305 | * to avoid namespace collision with explicit IDs. |
301 | */ | 306 | */ |
302 | ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL); | 307 | ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL); |
303 | if (ret < 0) | 308 | if (ret < 0) |
304 | goto err_out; | 309 | goto err_out; |
305 | pdev->id = ret; | 310 | pdev->id = ret; |
306 | pdev->id_auto = true; | 311 | pdev->id_auto = true; |
307 | dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id); | 312 | dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id); |
308 | break; | 313 | break; |
309 | } | 314 | } |
310 | 315 | ||
311 | for (i = 0; i < pdev->num_resources; i++) { | 316 | for (i = 0; i < pdev->num_resources; i++) { |
312 | struct resource *p, *r = &pdev->resource[i]; | 317 | struct resource *p, *r = &pdev->resource[i]; |
313 | 318 | ||
314 | if (r->name == NULL) | 319 | if (r->name == NULL) |
315 | r->name = dev_name(&pdev->dev); | 320 | r->name = dev_name(&pdev->dev); |
316 | 321 | ||
317 | p = r->parent; | 322 | p = r->parent; |
318 | if (!p) { | 323 | if (!p) { |
319 | if (resource_type(r) == IORESOURCE_MEM) | 324 | if (resource_type(r) == IORESOURCE_MEM) |
320 | p = &iomem_resource; | 325 | p = &iomem_resource; |
321 | else if (resource_type(r) == IORESOURCE_IO) | 326 | else if (resource_type(r) == IORESOURCE_IO) |
322 | p = &ioport_resource; | 327 | p = &ioport_resource; |
323 | } | 328 | } |
324 | 329 | ||
325 | if (p && insert_resource(p, r)) { | 330 | if (p && insert_resource(p, r)) { |
326 | dev_err(&pdev->dev, "failed to claim resource %d\n", i); | 331 | dev_err(&pdev->dev, "failed to claim resource %d\n", i); |
327 | ret = -EBUSY; | 332 | ret = -EBUSY; |
328 | goto failed; | 333 | goto failed; |
329 | } | 334 | } |
330 | } | 335 | } |
331 | 336 | ||
332 | pr_debug("Registering platform device '%s'. Parent at %s\n", | 337 | pr_debug("Registering platform device '%s'. Parent at %s\n", |
333 | dev_name(&pdev->dev), dev_name(pdev->dev.parent)); | 338 | dev_name(&pdev->dev), dev_name(pdev->dev.parent)); |
334 | 339 | ||
335 | ret = device_add(&pdev->dev); | 340 | ret = device_add(&pdev->dev); |
336 | if (ret == 0) | 341 | if (ret == 0) |
337 | return ret; | 342 | return ret; |
338 | 343 | ||
339 | failed: | 344 | failed: |
340 | if (pdev->id_auto) { | 345 | if (pdev->id_auto) { |
341 | ida_simple_remove(&platform_devid_ida, pdev->id); | 346 | ida_simple_remove(&platform_devid_ida, pdev->id); |
342 | pdev->id = PLATFORM_DEVID_AUTO; | 347 | pdev->id = PLATFORM_DEVID_AUTO; |
343 | } | 348 | } |
344 | 349 | ||
345 | while (--i >= 0) { | 350 | while (--i >= 0) { |
346 | struct resource *r = &pdev->resource[i]; | 351 | struct resource *r = &pdev->resource[i]; |
347 | unsigned long type = resource_type(r); | 352 | unsigned long type = resource_type(r); |
348 | 353 | ||
349 | if (type == IORESOURCE_MEM || type == IORESOURCE_IO) | 354 | if (type == IORESOURCE_MEM || type == IORESOURCE_IO) |
350 | release_resource(r); | 355 | release_resource(r); |
351 | } | 356 | } |
352 | 357 | ||
353 | err_out: | 358 | err_out: |
354 | return ret; | 359 | return ret; |
355 | } | 360 | } |
356 | EXPORT_SYMBOL_GPL(platform_device_add); | 361 | EXPORT_SYMBOL_GPL(platform_device_add); |
357 | 362 | ||
358 | /** | 363 | /** |
359 | * platform_device_del - remove a platform-level device | 364 | * platform_device_del - remove a platform-level device |
360 | * @pdev: platform device we're removing | 365 | * @pdev: platform device we're removing |
361 | * | 366 | * |
362 | * Note that this function will also release all memory- and port-based | 367 | * Note that this function will also release all memory- and port-based |
363 | * resources owned by the device (@dev->resource). This function must | 368 | * resources owned by the device (@dev->resource). This function must |
364 | * _only_ be externally called in error cases. All other usage is a bug. | 369 | * _only_ be externally called in error cases. All other usage is a bug. |
365 | */ | 370 | */ |
366 | void platform_device_del(struct platform_device *pdev) | 371 | void platform_device_del(struct platform_device *pdev) |
367 | { | 372 | { |
368 | int i; | 373 | int i; |
369 | 374 | ||
370 | if (pdev) { | 375 | if (pdev) { |
371 | device_del(&pdev->dev); | 376 | device_del(&pdev->dev); |
372 | 377 | ||
373 | if (pdev->id_auto) { | 378 | if (pdev->id_auto) { |
374 | ida_simple_remove(&platform_devid_ida, pdev->id); | 379 | ida_simple_remove(&platform_devid_ida, pdev->id); |
375 | pdev->id = PLATFORM_DEVID_AUTO; | 380 | pdev->id = PLATFORM_DEVID_AUTO; |
376 | } | 381 | } |
377 | 382 | ||
378 | for (i = 0; i < pdev->num_resources; i++) { | 383 | for (i = 0; i < pdev->num_resources; i++) { |
379 | struct resource *r = &pdev->resource[i]; | 384 | struct resource *r = &pdev->resource[i]; |
380 | unsigned long type = resource_type(r); | 385 | unsigned long type = resource_type(r); |
381 | 386 | ||
382 | if (type == IORESOURCE_MEM || type == IORESOURCE_IO) | 387 | if (type == IORESOURCE_MEM || type == IORESOURCE_IO) |
383 | release_resource(r); | 388 | release_resource(r); |
384 | } | 389 | } |
385 | } | 390 | } |
386 | } | 391 | } |
387 | EXPORT_SYMBOL_GPL(platform_device_del); | 392 | EXPORT_SYMBOL_GPL(platform_device_del); |
388 | 393 | ||
389 | /** | 394 | /** |
390 | * platform_device_register - add a platform-level device | 395 | * platform_device_register - add a platform-level device |
391 | * @pdev: platform device we're adding | 396 | * @pdev: platform device we're adding |
392 | */ | 397 | */ |
393 | int platform_device_register(struct platform_device *pdev) | 398 | int platform_device_register(struct platform_device *pdev) |
394 | { | 399 | { |
395 | device_initialize(&pdev->dev); | 400 | device_initialize(&pdev->dev); |
396 | arch_setup_pdev_archdata(pdev); | 401 | arch_setup_pdev_archdata(pdev); |
397 | return platform_device_add(pdev); | 402 | return platform_device_add(pdev); |
398 | } | 403 | } |
399 | EXPORT_SYMBOL_GPL(platform_device_register); | 404 | EXPORT_SYMBOL_GPL(platform_device_register); |
400 | 405 | ||
401 | /** | 406 | /** |
402 | * platform_device_unregister - unregister a platform-level device | 407 | * platform_device_unregister - unregister a platform-level device |
403 | * @pdev: platform device we're unregistering | 408 | * @pdev: platform device we're unregistering |
404 | * | 409 | * |
405 | * Unregistration is done in 2 steps. First we release all resources | 410 | * Unregistration is done in 2 steps. First we release all resources |
406 | * and remove it from the subsystem, then we drop reference count by | 411 | * and remove it from the subsystem, then we drop reference count by |
407 | * calling platform_device_put(). | 412 | * calling platform_device_put(). |
408 | */ | 413 | */ |
409 | void platform_device_unregister(struct platform_device *pdev) | 414 | void platform_device_unregister(struct platform_device *pdev) |
410 | { | 415 | { |
411 | platform_device_del(pdev); | 416 | platform_device_del(pdev); |
412 | platform_device_put(pdev); | 417 | platform_device_put(pdev); |
413 | } | 418 | } |
414 | EXPORT_SYMBOL_GPL(platform_device_unregister); | 419 | EXPORT_SYMBOL_GPL(platform_device_unregister); |
415 | 420 | ||
416 | /** | 421 | /** |
417 | * platform_device_register_full - add a platform-level device with | 422 | * platform_device_register_full - add a platform-level device with |
418 | * resources and platform-specific data | 423 | * resources and platform-specific data |
419 | * | 424 | * |
420 | * @pdevinfo: data used to create device | 425 | * @pdevinfo: data used to create device |
421 | * | 426 | * |
422 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | 427 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. |
423 | */ | 428 | */ |
424 | struct platform_device *platform_device_register_full( | 429 | struct platform_device *platform_device_register_full( |
425 | const struct platform_device_info *pdevinfo) | 430 | const struct platform_device_info *pdevinfo) |
426 | { | 431 | { |
427 | int ret = -ENOMEM; | 432 | int ret = -ENOMEM; |
428 | struct platform_device *pdev; | 433 | struct platform_device *pdev; |
429 | 434 | ||
430 | pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id); | 435 | pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id); |
431 | if (!pdev) | 436 | if (!pdev) |
432 | goto err_alloc; | 437 | goto err_alloc; |
433 | 438 | ||
434 | pdev->dev.parent = pdevinfo->parent; | 439 | pdev->dev.parent = pdevinfo->parent; |
435 | ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); | 440 | ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); |
436 | 441 | ||
437 | if (pdevinfo->dma_mask) { | 442 | if (pdevinfo->dma_mask) { |
438 | /* | 443 | /* |
439 | * This memory isn't freed when the device is put, | 444 | * This memory isn't freed when the device is put, |
440 | * I don't have a nice idea for that though. Conceptually | 445 | * I don't have a nice idea for that though. Conceptually |
441 | * dma_mask in struct device should not be a pointer. | 446 | * dma_mask in struct device should not be a pointer. |
442 | * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 | 447 | * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 |
443 | */ | 448 | */ |
444 | pdev->dev.dma_mask = | 449 | pdev->dev.dma_mask = |
445 | kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); | 450 | kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); |
446 | if (!pdev->dev.dma_mask) | 451 | if (!pdev->dev.dma_mask) |
447 | goto err; | 452 | goto err; |
448 | 453 | ||
449 | *pdev->dev.dma_mask = pdevinfo->dma_mask; | 454 | *pdev->dev.dma_mask = pdevinfo->dma_mask; |
450 | pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; | 455 | pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; |
451 | } | 456 | } |
452 | 457 | ||
453 | ret = platform_device_add_resources(pdev, | 458 | ret = platform_device_add_resources(pdev, |
454 | pdevinfo->res, pdevinfo->num_res); | 459 | pdevinfo->res, pdevinfo->num_res); |
455 | if (ret) | 460 | if (ret) |
456 | goto err; | 461 | goto err; |
457 | 462 | ||
458 | ret = platform_device_add_data(pdev, | 463 | ret = platform_device_add_data(pdev, |
459 | pdevinfo->data, pdevinfo->size_data); | 464 | pdevinfo->data, pdevinfo->size_data); |
460 | if (ret) | 465 | if (ret) |
461 | goto err; | 466 | goto err; |
462 | 467 | ||
463 | ret = platform_device_add(pdev); | 468 | ret = platform_device_add(pdev); |
464 | if (ret) { | 469 | if (ret) { |
465 | err: | 470 | err: |
466 | ACPI_COMPANION_SET(&pdev->dev, NULL); | 471 | ACPI_COMPANION_SET(&pdev->dev, NULL); |
467 | kfree(pdev->dev.dma_mask); | 472 | kfree(pdev->dev.dma_mask); |
468 | 473 | ||
469 | err_alloc: | 474 | err_alloc: |
470 | platform_device_put(pdev); | 475 | platform_device_put(pdev); |
471 | return ERR_PTR(ret); | 476 | return ERR_PTR(ret); |
472 | } | 477 | } |
473 | 478 | ||
474 | return pdev; | 479 | return pdev; |
475 | } | 480 | } |
476 | EXPORT_SYMBOL_GPL(platform_device_register_full); | 481 | EXPORT_SYMBOL_GPL(platform_device_register_full); |
477 | 482 | ||
478 | static int platform_drv_probe(struct device *_dev) | 483 | static int platform_drv_probe(struct device *_dev) |
479 | { | 484 | { |
480 | struct platform_driver *drv = to_platform_driver(_dev->driver); | 485 | struct platform_driver *drv = to_platform_driver(_dev->driver); |
481 | struct platform_device *dev = to_platform_device(_dev); | 486 | struct platform_device *dev = to_platform_device(_dev); |
482 | int ret; | 487 | int ret; |
483 | 488 | ||
484 | acpi_dev_pm_attach(_dev, true); | 489 | acpi_dev_pm_attach(_dev, true); |
485 | 490 | ||
486 | ret = drv->probe(dev); | 491 | ret = drv->probe(dev); |
487 | if (ret) | 492 | if (ret) |
488 | acpi_dev_pm_detach(_dev, true); | 493 | acpi_dev_pm_detach(_dev, true); |
489 | 494 | ||
490 | if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { | 495 | if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) { |
491 | dev_warn(_dev, "probe deferral not supported\n"); | 496 | dev_warn(_dev, "probe deferral not supported\n"); |
492 | ret = -ENXIO; | 497 | ret = -ENXIO; |
493 | } | 498 | } |
494 | 499 | ||
495 | return ret; | 500 | return ret; |
496 | } | 501 | } |
497 | 502 | ||
498 | static int platform_drv_probe_fail(struct device *_dev) | 503 | static int platform_drv_probe_fail(struct device *_dev) |
499 | { | 504 | { |
500 | return -ENXIO; | 505 | return -ENXIO; |
501 | } | 506 | } |
502 | 507 | ||
503 | static int platform_drv_remove(struct device *_dev) | 508 | static int platform_drv_remove(struct device *_dev) |
504 | { | 509 | { |
505 | struct platform_driver *drv = to_platform_driver(_dev->driver); | 510 | struct platform_driver *drv = to_platform_driver(_dev->driver); |
506 | struct platform_device *dev = to_platform_device(_dev); | 511 | struct platform_device *dev = to_platform_device(_dev); |
507 | int ret; | 512 | int ret; |
508 | 513 | ||
509 | ret = drv->remove(dev); | 514 | ret = drv->remove(dev); |
510 | acpi_dev_pm_detach(_dev, true); | 515 | acpi_dev_pm_detach(_dev, true); |
511 | 516 | ||
512 | return ret; | 517 | return ret; |
513 | } | 518 | } |
514 | 519 | ||
515 | static void platform_drv_shutdown(struct device *_dev) | 520 | static void platform_drv_shutdown(struct device *_dev) |
516 | { | 521 | { |
517 | struct platform_driver *drv = to_platform_driver(_dev->driver); | 522 | struct platform_driver *drv = to_platform_driver(_dev->driver); |
518 | struct platform_device *dev = to_platform_device(_dev); | 523 | struct platform_device *dev = to_platform_device(_dev); |
519 | 524 | ||
520 | drv->shutdown(dev); | 525 | drv->shutdown(dev); |
521 | acpi_dev_pm_detach(_dev, true); | 526 | acpi_dev_pm_detach(_dev, true); |
522 | } | 527 | } |
523 | 528 | ||
524 | /** | 529 | /** |
525 | * __platform_driver_register - register a driver for platform-level devices | 530 | * __platform_driver_register - register a driver for platform-level devices |
526 | * @drv: platform driver structure | 531 | * @drv: platform driver structure |
527 | * @owner: owning module/driver | 532 | * @owner: owning module/driver |
528 | */ | 533 | */ |
529 | int __platform_driver_register(struct platform_driver *drv, | 534 | int __platform_driver_register(struct platform_driver *drv, |
530 | struct module *owner) | 535 | struct module *owner) |
531 | { | 536 | { |
532 | drv->driver.owner = owner; | 537 | drv->driver.owner = owner; |
533 | drv->driver.bus = &platform_bus_type; | 538 | drv->driver.bus = &platform_bus_type; |
534 | if (drv->probe) | 539 | if (drv->probe) |
535 | drv->driver.probe = platform_drv_probe; | 540 | drv->driver.probe = platform_drv_probe; |
536 | if (drv->remove) | 541 | if (drv->remove) |
537 | drv->driver.remove = platform_drv_remove; | 542 | drv->driver.remove = platform_drv_remove; |
538 | if (drv->shutdown) | 543 | if (drv->shutdown) |
539 | drv->driver.shutdown = platform_drv_shutdown; | 544 | drv->driver.shutdown = platform_drv_shutdown; |
540 | 545 | ||
541 | return driver_register(&drv->driver); | 546 | return driver_register(&drv->driver); |
542 | } | 547 | } |
543 | EXPORT_SYMBOL_GPL(__platform_driver_register); | 548 | EXPORT_SYMBOL_GPL(__platform_driver_register); |
544 | 549 | ||
545 | /** | 550 | /** |
546 | * platform_driver_unregister - unregister a driver for platform-level devices | 551 | * platform_driver_unregister - unregister a driver for platform-level devices |
547 | * @drv: platform driver structure | 552 | * @drv: platform driver structure |
548 | */ | 553 | */ |
549 | void platform_driver_unregister(struct platform_driver *drv) | 554 | void platform_driver_unregister(struct platform_driver *drv) |
550 | { | 555 | { |
551 | driver_unregister(&drv->driver); | 556 | driver_unregister(&drv->driver); |
552 | } | 557 | } |
553 | EXPORT_SYMBOL_GPL(platform_driver_unregister); | 558 | EXPORT_SYMBOL_GPL(platform_driver_unregister); |
554 | 559 | ||
555 | /** | 560 | /** |
556 | * platform_driver_probe - register driver for non-hotpluggable device | 561 | * platform_driver_probe - register driver for non-hotpluggable device |
557 | * @drv: platform driver structure | 562 | * @drv: platform driver structure |
558 | * @probe: the driver probe routine, probably from an __init section | 563 | * @probe: the driver probe routine, probably from an __init section |
559 | * | 564 | * |
560 | * Use this instead of platform_driver_register() when you know the device | 565 | * Use this instead of platform_driver_register() when you know the device |
561 | * is not hotpluggable and has already been registered, and you want to | 566 | * is not hotpluggable and has already been registered, and you want to |
562 | * remove its run-once probe() infrastructure from memory after the driver | 567 | * remove its run-once probe() infrastructure from memory after the driver |
563 | * has bound to the device. | 568 | * has bound to the device. |
564 | * | 569 | * |
565 | * One typical use for this would be with drivers for controllers integrated | 570 | * One typical use for this would be with drivers for controllers integrated |
566 | * into system-on-chip processors, where the controller devices have been | 571 | * into system-on-chip processors, where the controller devices have been |
567 | * configured as part of board setup. | 572 | * configured as part of board setup. |
568 | * | 573 | * |
569 | * Note that this is incompatible with deferred probing. | 574 | * Note that this is incompatible with deferred probing. |
570 | * | 575 | * |
571 | * Returns zero if the driver registered and bound to a device, else returns | 576 | * Returns zero if the driver registered and bound to a device, else returns |
572 | * a negative error code and with the driver not registered. | 577 | * a negative error code and with the driver not registered. |
573 | */ | 578 | */ |
574 | int __init_or_module platform_driver_probe(struct platform_driver *drv, | 579 | int __init_or_module platform_driver_probe(struct platform_driver *drv, |
575 | int (*probe)(struct platform_device *)) | 580 | int (*probe)(struct platform_device *)) |
576 | { | 581 | { |
577 | int retval, code; | 582 | int retval, code; |
578 | 583 | ||
579 | /* | 584 | /* |
580 | * Prevent driver from requesting probe deferral to avoid further | 585 | * Prevent driver from requesting probe deferral to avoid further |
581 | * futile probe attempts. | 586 | * futile probe attempts. |
582 | */ | 587 | */ |
583 | drv->prevent_deferred_probe = true; | 588 | drv->prevent_deferred_probe = true; |
584 | 589 | ||
585 | /* make sure driver won't have bind/unbind attributes */ | 590 | /* make sure driver won't have bind/unbind attributes */ |
586 | drv->driver.suppress_bind_attrs = true; | 591 | drv->driver.suppress_bind_attrs = true; |
587 | 592 | ||
588 | /* temporary section violation during probe() */ | 593 | /* temporary section violation during probe() */ |
589 | drv->probe = probe; | 594 | drv->probe = probe; |
590 | retval = code = platform_driver_register(drv); | 595 | retval = code = platform_driver_register(drv); |
591 | 596 | ||
592 | /* | 597 | /* |
593 | * Fixup that section violation, being paranoid about code scanning | 598 | * Fixup that section violation, being paranoid about code scanning |
594 | * the list of drivers in order to probe new devices. Check to see | 599 | * the list of drivers in order to probe new devices. Check to see |
595 | * if the probe was successful, and make sure any forced probes of | 600 | * if the probe was successful, and make sure any forced probes of |
596 | * new devices fail. | 601 | * new devices fail. |
597 | */ | 602 | */ |
598 | spin_lock(&drv->driver.bus->p->klist_drivers.k_lock); | 603 | spin_lock(&drv->driver.bus->p->klist_drivers.k_lock); |
599 | drv->probe = NULL; | 604 | drv->probe = NULL; |
600 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) | 605 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) |
601 | retval = -ENODEV; | 606 | retval = -ENODEV; |
602 | drv->driver.probe = platform_drv_probe_fail; | 607 | drv->driver.probe = platform_drv_probe_fail; |
603 | spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock); | 608 | spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock); |
604 | 609 | ||
605 | if (code != retval) | 610 | if (code != retval) |
606 | platform_driver_unregister(drv); | 611 | platform_driver_unregister(drv); |
607 | return retval; | 612 | return retval; |
608 | } | 613 | } |
609 | EXPORT_SYMBOL_GPL(platform_driver_probe); | 614 | EXPORT_SYMBOL_GPL(platform_driver_probe); |
610 | 615 | ||
611 | /** | 616 | /** |
612 | * platform_create_bundle - register driver and create corresponding device | 617 | * platform_create_bundle - register driver and create corresponding device |
613 | * @driver: platform driver structure | 618 | * @driver: platform driver structure |
614 | * @probe: the driver probe routine, probably from an __init section | 619 | * @probe: the driver probe routine, probably from an __init section |
615 | * @res: set of resources that needs to be allocated for the device | 620 | * @res: set of resources that needs to be allocated for the device |
616 | * @n_res: number of resources | 621 | * @n_res: number of resources |
617 | * @data: platform specific data for this platform device | 622 | * @data: platform specific data for this platform device |
618 | * @size: size of platform specific data | 623 | * @size: size of platform specific data |
619 | * | 624 | * |
620 | * Use this in legacy-style modules that probe hardware directly and | 625 | * Use this in legacy-style modules that probe hardware directly and |
621 | * register a single platform device and corresponding platform driver. | 626 | * register a single platform device and corresponding platform driver. |
622 | * | 627 | * |
623 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | 628 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. |
624 | */ | 629 | */ |
625 | struct platform_device * __init_or_module platform_create_bundle( | 630 | struct platform_device * __init_or_module platform_create_bundle( |
626 | struct platform_driver *driver, | 631 | struct platform_driver *driver, |
627 | int (*probe)(struct platform_device *), | 632 | int (*probe)(struct platform_device *), |
628 | struct resource *res, unsigned int n_res, | 633 | struct resource *res, unsigned int n_res, |
629 | const void *data, size_t size) | 634 | const void *data, size_t size) |
630 | { | 635 | { |
631 | struct platform_device *pdev; | 636 | struct platform_device *pdev; |
632 | int error; | 637 | int error; |
633 | 638 | ||
634 | pdev = platform_device_alloc(driver->driver.name, -1); | 639 | pdev = platform_device_alloc(driver->driver.name, -1); |
635 | if (!pdev) { | 640 | if (!pdev) { |
636 | error = -ENOMEM; | 641 | error = -ENOMEM; |
637 | goto err_out; | 642 | goto err_out; |
638 | } | 643 | } |
639 | 644 | ||
640 | error = platform_device_add_resources(pdev, res, n_res); | 645 | error = platform_device_add_resources(pdev, res, n_res); |
641 | if (error) | 646 | if (error) |
642 | goto err_pdev_put; | 647 | goto err_pdev_put; |
643 | 648 | ||
644 | error = platform_device_add_data(pdev, data, size); | 649 | error = platform_device_add_data(pdev, data, size); |
645 | if (error) | 650 | if (error) |
646 | goto err_pdev_put; | 651 | goto err_pdev_put; |
647 | 652 | ||
648 | error = platform_device_add(pdev); | 653 | error = platform_device_add(pdev); |
649 | if (error) | 654 | if (error) |
650 | goto err_pdev_put; | 655 | goto err_pdev_put; |
651 | 656 | ||
652 | error = platform_driver_probe(driver, probe); | 657 | error = platform_driver_probe(driver, probe); |
653 | if (error) | 658 | if (error) |
654 | goto err_pdev_del; | 659 | goto err_pdev_del; |
655 | 660 | ||
656 | return pdev; | 661 | return pdev; |
657 | 662 | ||
658 | err_pdev_del: | 663 | err_pdev_del: |
659 | platform_device_del(pdev); | 664 | platform_device_del(pdev); |
660 | err_pdev_put: | 665 | err_pdev_put: |
661 | platform_device_put(pdev); | 666 | platform_device_put(pdev); |
662 | err_out: | 667 | err_out: |
663 | return ERR_PTR(error); | 668 | return ERR_PTR(error); |
664 | } | 669 | } |
665 | EXPORT_SYMBOL_GPL(platform_create_bundle); | 670 | EXPORT_SYMBOL_GPL(platform_create_bundle); |
666 | 671 | ||
667 | /* modalias support enables more hands-off userspace setup: | 672 | /* modalias support enables more hands-off userspace setup: |
668 | * (a) environment variable lets new-style hotplug events work once system is | 673 | * (a) environment variable lets new-style hotplug events work once system is |
669 | * fully running: "modprobe $MODALIAS" | 674 | * fully running: "modprobe $MODALIAS" |
670 | * (b) sysfs attribute lets new-style coldplug recover from hotplug events | 675 | * (b) sysfs attribute lets new-style coldplug recover from hotplug events |
671 | * mishandled before system is fully running: "modprobe $(cat modalias)" | 676 | * mishandled before system is fully running: "modprobe $(cat modalias)" |
672 | */ | 677 | */ |
673 | static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | 678 | static ssize_t modalias_show(struct device *dev, struct device_attribute *a, |
674 | char *buf) | 679 | char *buf) |
675 | { | 680 | { |
676 | struct platform_device *pdev = to_platform_device(dev); | 681 | struct platform_device *pdev = to_platform_device(dev); |
677 | int len; | 682 | int len; |
678 | 683 | ||
679 | len = of_device_get_modalias(dev, buf, PAGE_SIZE -1); | 684 | len = of_device_get_modalias(dev, buf, PAGE_SIZE -1); |
680 | if (len != -ENODEV) | 685 | if (len != -ENODEV) |
681 | return len; | 686 | return len; |
682 | 687 | ||
683 | len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); | 688 | len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); |
684 | if (len != -ENODEV) | 689 | if (len != -ENODEV) |
685 | return len; | 690 | return len; |
686 | 691 | ||
687 | len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | 692 | len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); |
688 | 693 | ||
689 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 694 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
690 | } | 695 | } |
691 | static DEVICE_ATTR_RO(modalias); | 696 | static DEVICE_ATTR_RO(modalias); |
692 | 697 | ||
693 | static struct attribute *platform_dev_attrs[] = { | 698 | static struct attribute *platform_dev_attrs[] = { |
694 | &dev_attr_modalias.attr, | 699 | &dev_attr_modalias.attr, |
695 | NULL, | 700 | NULL, |
696 | }; | 701 | }; |
697 | ATTRIBUTE_GROUPS(platform_dev); | 702 | ATTRIBUTE_GROUPS(platform_dev); |
698 | 703 | ||
699 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | 704 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) |
700 | { | 705 | { |
701 | struct platform_device *pdev = to_platform_device(dev); | 706 | struct platform_device *pdev = to_platform_device(dev); |
702 | int rc; | 707 | int rc; |
703 | 708 | ||
704 | /* Some devices have extra OF data and an OF-style MODALIAS */ | 709 | /* Some devices have extra OF data and an OF-style MODALIAS */ |
705 | rc = of_device_uevent_modalias(dev, env); | 710 | rc = of_device_uevent_modalias(dev, env); |
706 | if (rc != -ENODEV) | 711 | if (rc != -ENODEV) |
707 | return rc; | 712 | return rc; |
708 | 713 | ||
709 | rc = acpi_device_uevent_modalias(dev, env); | 714 | rc = acpi_device_uevent_modalias(dev, env); |
710 | if (rc != -ENODEV) | 715 | if (rc != -ENODEV) |
711 | return rc; | 716 | return rc; |
712 | 717 | ||
713 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, | 718 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
714 | pdev->name); | 719 | pdev->name); |
715 | return 0; | 720 | return 0; |
716 | } | 721 | } |
717 | 722 | ||
718 | static const struct platform_device_id *platform_match_id( | 723 | static const struct platform_device_id *platform_match_id( |
719 | const struct platform_device_id *id, | 724 | const struct platform_device_id *id, |
720 | struct platform_device *pdev) | 725 | struct platform_device *pdev) |
721 | { | 726 | { |
722 | while (id->name[0]) { | 727 | while (id->name[0]) { |
723 | if (strcmp(pdev->name, id->name) == 0) { | 728 | if (strcmp(pdev->name, id->name) == 0) { |
724 | pdev->id_entry = id; | 729 | pdev->id_entry = id; |
725 | return id; | 730 | return id; |
726 | } | 731 | } |
727 | id++; | 732 | id++; |
728 | } | 733 | } |
729 | return NULL; | 734 | return NULL; |
730 | } | 735 | } |
731 | 736 | ||
732 | /** | 737 | /** |
733 | * platform_match - bind platform device to platform driver. | 738 | * platform_match - bind platform device to platform driver. |
734 | * @dev: device. | 739 | * @dev: device. |
735 | * @drv: driver. | 740 | * @drv: driver. |
736 | * | 741 | * |
737 | * Platform device IDs are assumed to be encoded like this: | 742 | * Platform device IDs are assumed to be encoded like this: |
738 | * "<name><instance>", where <name> is a short description of the type of | 743 | * "<name><instance>", where <name> is a short description of the type of |
739 | * device, like "pci" or "floppy", and <instance> is the enumerated | 744 | * device, like "pci" or "floppy", and <instance> is the enumerated |
740 | * instance of the device, like '0' or '42'. Driver IDs are simply | 745 | * instance of the device, like '0' or '42'. Driver IDs are simply |
741 | * "<name>". So, extract the <name> from the platform_device structure, | 746 | * "<name>". So, extract the <name> from the platform_device structure, |
742 | * and compare it against the name of the driver. Return whether they match | 747 | * and compare it against the name of the driver. Return whether they match |
743 | * or not. | 748 | * or not. |
744 | */ | 749 | */ |
745 | static int platform_match(struct device *dev, struct device_driver *drv) | 750 | static int platform_match(struct device *dev, struct device_driver *drv) |
746 | { | 751 | { |
747 | struct platform_device *pdev = to_platform_device(dev); | 752 | struct platform_device *pdev = to_platform_device(dev); |
748 | struct platform_driver *pdrv = to_platform_driver(drv); | 753 | struct platform_driver *pdrv = to_platform_driver(drv); |
749 | 754 | ||
750 | /* Attempt an OF style match first */ | 755 | /* Attempt an OF style match first */ |
751 | if (of_driver_match_device(dev, drv)) | 756 | if (of_driver_match_device(dev, drv)) |
752 | return 1; | 757 | return 1; |
753 | 758 | ||
754 | /* Then try ACPI style match */ | 759 | /* Then try ACPI style match */ |
755 | if (acpi_driver_match_device(dev, drv)) | 760 | if (acpi_driver_match_device(dev, drv)) |
756 | return 1; | 761 | return 1; |
757 | 762 | ||
758 | /* Then try to match against the id table */ | 763 | /* Then try to match against the id table */ |
759 | if (pdrv->id_table) | 764 | if (pdrv->id_table) |
760 | return platform_match_id(pdrv->id_table, pdev) != NULL; | 765 | return platform_match_id(pdrv->id_table, pdev) != NULL; |
761 | 766 | ||
762 | /* fall-back to driver name match */ | 767 | /* fall-back to driver name match */ |
763 | return (strcmp(pdev->name, drv->name) == 0); | 768 | return (strcmp(pdev->name, drv->name) == 0); |
764 | } | 769 | } |
765 | 770 | ||
766 | #ifdef CONFIG_PM_SLEEP | 771 | #ifdef CONFIG_PM_SLEEP |
767 | 772 | ||
768 | static int platform_legacy_suspend(struct device *dev, pm_message_t mesg) | 773 | static int platform_legacy_suspend(struct device *dev, pm_message_t mesg) |
769 | { | 774 | { |
770 | struct platform_driver *pdrv = to_platform_driver(dev->driver); | 775 | struct platform_driver *pdrv = to_platform_driver(dev->driver); |
771 | struct platform_device *pdev = to_platform_device(dev); | 776 | struct platform_device *pdev = to_platform_device(dev); |
772 | int ret = 0; | 777 | int ret = 0; |
773 | 778 | ||
774 | if (dev->driver && pdrv->suspend) | 779 | if (dev->driver && pdrv->suspend) |
775 | ret = pdrv->suspend(pdev, mesg); | 780 | ret = pdrv->suspend(pdev, mesg); |
776 | 781 | ||
777 | return ret; | 782 | return ret; |
778 | } | 783 | } |
779 | 784 | ||
780 | static int platform_legacy_resume(struct device *dev) | 785 | static int platform_legacy_resume(struct device *dev) |
781 | { | 786 | { |
782 | struct platform_driver *pdrv = to_platform_driver(dev->driver); | 787 | struct platform_driver *pdrv = to_platform_driver(dev->driver); |
783 | struct platform_device *pdev = to_platform_device(dev); | 788 | struct platform_device *pdev = to_platform_device(dev); |
784 | int ret = 0; | 789 | int ret = 0; |
785 | 790 | ||
786 | if (dev->driver && pdrv->resume) | 791 | if (dev->driver && pdrv->resume) |
787 | ret = pdrv->resume(pdev); | 792 | ret = pdrv->resume(pdev); |
788 | 793 | ||
789 | return ret; | 794 | return ret; |
790 | } | 795 | } |
791 | 796 | ||
792 | #endif /* CONFIG_PM_SLEEP */ | 797 | #endif /* CONFIG_PM_SLEEP */ |
793 | 798 | ||
794 | #ifdef CONFIG_SUSPEND | 799 | #ifdef CONFIG_SUSPEND |
795 | 800 | ||
796 | int platform_pm_suspend(struct device *dev) | 801 | int platform_pm_suspend(struct device *dev) |
797 | { | 802 | { |
798 | struct device_driver *drv = dev->driver; | 803 | struct device_driver *drv = dev->driver; |
799 | int ret = 0; | 804 | int ret = 0; |
800 | 805 | ||
801 | if (!drv) | 806 | if (!drv) |
802 | return 0; | 807 | return 0; |
803 | 808 | ||
804 | if (drv->pm) { | 809 | if (drv->pm) { |
805 | if (drv->pm->suspend) | 810 | if (drv->pm->suspend) |
806 | ret = drv->pm->suspend(dev); | 811 | ret = drv->pm->suspend(dev); |
807 | } else { | 812 | } else { |
808 | ret = platform_legacy_suspend(dev, PMSG_SUSPEND); | 813 | ret = platform_legacy_suspend(dev, PMSG_SUSPEND); |
809 | } | 814 | } |
810 | 815 | ||
811 | return ret; | 816 | return ret; |
812 | } | 817 | } |
813 | 818 | ||
814 | int platform_pm_resume(struct device *dev) | 819 | int platform_pm_resume(struct device *dev) |
815 | { | 820 | { |
816 | struct device_driver *drv = dev->driver; | 821 | struct device_driver *drv = dev->driver; |
817 | int ret = 0; | 822 | int ret = 0; |
818 | 823 | ||
819 | if (!drv) | 824 | if (!drv) |
820 | return 0; | 825 | return 0; |
821 | 826 | ||
822 | if (drv->pm) { | 827 | if (drv->pm) { |
823 | if (drv->pm->resume) | 828 | if (drv->pm->resume) |
824 | ret = drv->pm->resume(dev); | 829 | ret = drv->pm->resume(dev); |
825 | } else { | 830 | } else { |
826 | ret = platform_legacy_resume(dev); | 831 | ret = platform_legacy_resume(dev); |
827 | } | 832 | } |
828 | 833 | ||
829 | return ret; | 834 | return ret; |
830 | } | 835 | } |
831 | 836 | ||
832 | #endif /* CONFIG_SUSPEND */ | 837 | #endif /* CONFIG_SUSPEND */ |
833 | 838 | ||
834 | #ifdef CONFIG_HIBERNATE_CALLBACKS | 839 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
835 | 840 | ||
836 | int platform_pm_freeze(struct device *dev) | 841 | int platform_pm_freeze(struct device *dev) |
837 | { | 842 | { |
838 | struct device_driver *drv = dev->driver; | 843 | struct device_driver *drv = dev->driver; |
839 | int ret = 0; | 844 | int ret = 0; |
840 | 845 | ||
841 | if (!drv) | 846 | if (!drv) |
842 | return 0; | 847 | return 0; |
843 | 848 | ||
844 | if (drv->pm) { | 849 | if (drv->pm) { |
845 | if (drv->pm->freeze) | 850 | if (drv->pm->freeze) |
846 | ret = drv->pm->freeze(dev); | 851 | ret = drv->pm->freeze(dev); |
847 | } else { | 852 | } else { |
848 | ret = platform_legacy_suspend(dev, PMSG_FREEZE); | 853 | ret = platform_legacy_suspend(dev, PMSG_FREEZE); |
849 | } | 854 | } |
850 | 855 | ||
851 | return ret; | 856 | return ret; |
852 | } | 857 | } |
853 | 858 | ||
854 | int platform_pm_thaw(struct device *dev) | 859 | int platform_pm_thaw(struct device *dev) |
855 | { | 860 | { |
856 | struct device_driver *drv = dev->driver; | 861 | struct device_driver *drv = dev->driver; |
857 | int ret = 0; | 862 | int ret = 0; |
858 | 863 | ||
859 | if (!drv) | 864 | if (!drv) |
860 | return 0; | 865 | return 0; |
861 | 866 | ||
862 | if (drv->pm) { | 867 | if (drv->pm) { |
863 | if (drv->pm->thaw) | 868 | if (drv->pm->thaw) |
864 | ret = drv->pm->thaw(dev); | 869 | ret = drv->pm->thaw(dev); |
865 | } else { | 870 | } else { |
866 | ret = platform_legacy_resume(dev); | 871 | ret = platform_legacy_resume(dev); |
867 | } | 872 | } |
868 | 873 | ||
869 | return ret; | 874 | return ret; |
870 | } | 875 | } |
871 | 876 | ||
872 | int platform_pm_poweroff(struct device *dev) | 877 | int platform_pm_poweroff(struct device *dev) |
873 | { | 878 | { |
874 | struct device_driver *drv = dev->driver; | 879 | struct device_driver *drv = dev->driver; |
875 | int ret = 0; | 880 | int ret = 0; |
876 | 881 | ||
877 | if (!drv) | 882 | if (!drv) |
878 | return 0; | 883 | return 0; |
879 | 884 | ||
880 | if (drv->pm) { | 885 | if (drv->pm) { |
881 | if (drv->pm->poweroff) | 886 | if (drv->pm->poweroff) |
882 | ret = drv->pm->poweroff(dev); | 887 | ret = drv->pm->poweroff(dev); |
883 | } else { | 888 | } else { |
884 | ret = platform_legacy_suspend(dev, PMSG_HIBERNATE); | 889 | ret = platform_legacy_suspend(dev, PMSG_HIBERNATE); |
885 | } | 890 | } |
886 | 891 | ||
887 | return ret; | 892 | return ret; |
888 | } | 893 | } |
889 | 894 | ||
890 | int platform_pm_restore(struct device *dev) | 895 | int platform_pm_restore(struct device *dev) |
891 | { | 896 | { |
892 | struct device_driver *drv = dev->driver; | 897 | struct device_driver *drv = dev->driver; |
893 | int ret = 0; | 898 | int ret = 0; |
894 | 899 | ||
895 | if (!drv) | 900 | if (!drv) |
896 | return 0; | 901 | return 0; |
897 | 902 | ||
898 | if (drv->pm) { | 903 | if (drv->pm) { |
899 | if (drv->pm->restore) | 904 | if (drv->pm->restore) |
900 | ret = drv->pm->restore(dev); | 905 | ret = drv->pm->restore(dev); |
901 | } else { | 906 | } else { |
902 | ret = platform_legacy_resume(dev); | 907 | ret = platform_legacy_resume(dev); |
903 | } | 908 | } |
904 | 909 | ||
905 | return ret; | 910 | return ret; |
906 | } | 911 | } |
907 | 912 | ||
908 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ | 913 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ |
909 | 914 | ||
910 | static const struct dev_pm_ops platform_dev_pm_ops = { | 915 | static const struct dev_pm_ops platform_dev_pm_ops = { |
911 | .runtime_suspend = pm_generic_runtime_suspend, | 916 | .runtime_suspend = pm_generic_runtime_suspend, |
912 | .runtime_resume = pm_generic_runtime_resume, | 917 | .runtime_resume = pm_generic_runtime_resume, |
913 | USE_PLATFORM_PM_SLEEP_OPS | 918 | USE_PLATFORM_PM_SLEEP_OPS |
914 | }; | 919 | }; |
915 | 920 | ||
916 | struct bus_type platform_bus_type = { | 921 | struct bus_type platform_bus_type = { |
917 | .name = "platform", | 922 | .name = "platform", |
918 | .dev_groups = platform_dev_groups, | 923 | .dev_groups = platform_dev_groups, |
919 | .match = platform_match, | 924 | .match = platform_match, |
920 | .uevent = platform_uevent, | 925 | .uevent = platform_uevent, |
921 | .pm = &platform_dev_pm_ops, | 926 | .pm = &platform_dev_pm_ops, |
922 | }; | 927 | }; |
923 | EXPORT_SYMBOL_GPL(platform_bus_type); | 928 | EXPORT_SYMBOL_GPL(platform_bus_type); |
924 | 929 | ||
925 | int __init platform_bus_init(void) | 930 | int __init platform_bus_init(void) |
926 | { | 931 | { |
927 | int error; | 932 | int error; |
928 | 933 | ||
929 | early_platform_cleanup(); | 934 | early_platform_cleanup(); |
930 | 935 | ||
931 | error = device_register(&platform_bus); | 936 | error = device_register(&platform_bus); |
932 | if (error) | 937 | if (error) |
933 | return error; | 938 | return error; |
934 | error = bus_register(&platform_bus_type); | 939 | error = bus_register(&platform_bus_type); |
935 | if (error) | 940 | if (error) |
936 | device_unregister(&platform_bus); | 941 | device_unregister(&platform_bus); |
937 | return error; | 942 | return error; |
938 | } | 943 | } |
939 | 944 | ||
940 | #ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK | 945 | #ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK |
941 | u64 dma_get_required_mask(struct device *dev) | 946 | u64 dma_get_required_mask(struct device *dev) |
942 | { | 947 | { |
943 | u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT); | 948 | u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT); |
944 | u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT)); | 949 | u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT)); |
945 | u64 mask; | 950 | u64 mask; |
946 | 951 | ||
947 | if (!high_totalram) { | 952 | if (!high_totalram) { |
948 | /* convert to mask just covering totalram */ | 953 | /* convert to mask just covering totalram */ |
949 | low_totalram = (1 << (fls(low_totalram) - 1)); | 954 | low_totalram = (1 << (fls(low_totalram) - 1)); |
950 | low_totalram += low_totalram - 1; | 955 | low_totalram += low_totalram - 1; |
951 | mask = low_totalram; | 956 | mask = low_totalram; |
952 | } else { | 957 | } else { |
953 | high_totalram = (1 << (fls(high_totalram) - 1)); | 958 | high_totalram = (1 << (fls(high_totalram) - 1)); |
954 | high_totalram += high_totalram - 1; | 959 | high_totalram += high_totalram - 1; |
955 | mask = (((u64)high_totalram) << 32) + 0xffffffff; | 960 | mask = (((u64)high_totalram) << 32) + 0xffffffff; |
956 | } | 961 | } |
957 | return mask; | 962 | return mask; |
958 | } | 963 | } |
959 | EXPORT_SYMBOL_GPL(dma_get_required_mask); | 964 | EXPORT_SYMBOL_GPL(dma_get_required_mask); |
960 | #endif | 965 | #endif |
961 | 966 | ||
962 | static __initdata LIST_HEAD(early_platform_driver_list); | 967 | static __initdata LIST_HEAD(early_platform_driver_list); |
963 | static __initdata LIST_HEAD(early_platform_device_list); | 968 | static __initdata LIST_HEAD(early_platform_device_list); |
964 | 969 | ||
965 | /** | 970 | /** |
966 | * early_platform_driver_register - register early platform driver | 971 | * early_platform_driver_register - register early platform driver |
967 | * @epdrv: early_platform driver structure | 972 | * @epdrv: early_platform driver structure |
968 | * @buf: string passed from early_param() | 973 | * @buf: string passed from early_param() |
969 | * | 974 | * |
970 | * Helper function for early_platform_init() / early_platform_init_buffer() | 975 | * Helper function for early_platform_init() / early_platform_init_buffer() |
971 | */ | 976 | */ |
972 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, | 977 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, |
973 | char *buf) | 978 | char *buf) |
974 | { | 979 | { |
975 | char *tmp; | 980 | char *tmp; |
976 | int n; | 981 | int n; |
977 | 982 | ||
978 | /* Simply add the driver to the end of the global list. | 983 | /* Simply add the driver to the end of the global list. |
979 | * Drivers will by default be put on the list in compiled-in order. | 984 | * Drivers will by default be put on the list in compiled-in order. |
980 | */ | 985 | */ |
981 | if (!epdrv->list.next) { | 986 | if (!epdrv->list.next) { |
982 | INIT_LIST_HEAD(&epdrv->list); | 987 | INIT_LIST_HEAD(&epdrv->list); |
983 | list_add_tail(&epdrv->list, &early_platform_driver_list); | 988 | list_add_tail(&epdrv->list, &early_platform_driver_list); |
984 | } | 989 | } |
985 | 990 | ||
986 | /* If the user has specified device then make sure the driver | 991 | /* If the user has specified device then make sure the driver |
987 | * gets prioritized. The driver of the last device specified on | 992 | * gets prioritized. The driver of the last device specified on |
988 | * command line will be put first on the list. | 993 | * command line will be put first on the list. |
989 | */ | 994 | */ |
990 | n = strlen(epdrv->pdrv->driver.name); | 995 | n = strlen(epdrv->pdrv->driver.name); |
991 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { | 996 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { |
992 | list_move(&epdrv->list, &early_platform_driver_list); | 997 | list_move(&epdrv->list, &early_platform_driver_list); |
993 | 998 | ||
994 | /* Allow passing parameters after device name */ | 999 | /* Allow passing parameters after device name */ |
995 | if (buf[n] == '\0' || buf[n] == ',') | 1000 | if (buf[n] == '\0' || buf[n] == ',') |
996 | epdrv->requested_id = -1; | 1001 | epdrv->requested_id = -1; |
997 | else { | 1002 | else { |
998 | epdrv->requested_id = simple_strtoul(&buf[n + 1], | 1003 | epdrv->requested_id = simple_strtoul(&buf[n + 1], |
999 | &tmp, 10); | 1004 | &tmp, 10); |
1000 | 1005 | ||
1001 | if (buf[n] != '.' || (tmp == &buf[n + 1])) { | 1006 | if (buf[n] != '.' || (tmp == &buf[n + 1])) { |
1002 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; | 1007 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; |
1003 | n = 0; | 1008 | n = 0; |
1004 | } else | 1009 | } else |
1005 | n += strcspn(&buf[n + 1], ",") + 1; | 1010 | n += strcspn(&buf[n + 1], ",") + 1; |
1006 | } | 1011 | } |
1007 | 1012 | ||
1008 | if (buf[n] == ',') | 1013 | if (buf[n] == ',') |
1009 | n++; | 1014 | n++; |
1010 | 1015 | ||
1011 | if (epdrv->bufsize) { | 1016 | if (epdrv->bufsize) { |
1012 | memcpy(epdrv->buffer, &buf[n], | 1017 | memcpy(epdrv->buffer, &buf[n], |
1013 | min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); | 1018 | min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); |
1014 | epdrv->buffer[epdrv->bufsize - 1] = '\0'; | 1019 | epdrv->buffer[epdrv->bufsize - 1] = '\0'; |
1015 | } | 1020 | } |
1016 | } | 1021 | } |
1017 | 1022 | ||
1018 | return 0; | 1023 | return 0; |
1019 | } | 1024 | } |
1020 | 1025 | ||
1021 | /** | 1026 | /** |
1022 | * early_platform_add_devices - adds a number of early platform devices | 1027 | * early_platform_add_devices - adds a number of early platform devices |
1023 | * @devs: array of early platform devices to add | 1028 | * @devs: array of early platform devices to add |
1024 | * @num: number of early platform devices in array | 1029 | * @num: number of early platform devices in array |
1025 | * | 1030 | * |
1026 | * Used by early architecture code to register early platform devices and | 1031 | * Used by early architecture code to register early platform devices and |
1027 | * their platform data. | 1032 | * their platform data. |
1028 | */ | 1033 | */ |
1029 | void __init early_platform_add_devices(struct platform_device **devs, int num) | 1034 | void __init early_platform_add_devices(struct platform_device **devs, int num) |
1030 | { | 1035 | { |
1031 | struct device *dev; | 1036 | struct device *dev; |
1032 | int i; | 1037 | int i; |
1033 | 1038 | ||
1034 | /* simply add the devices to list */ | 1039 | /* simply add the devices to list */ |
1035 | for (i = 0; i < num; i++) { | 1040 | for (i = 0; i < num; i++) { |
1036 | dev = &devs[i]->dev; | 1041 | dev = &devs[i]->dev; |
1037 | 1042 | ||
1038 | if (!dev->devres_head.next) { | 1043 | if (!dev->devres_head.next) { |
1039 | pm_runtime_early_init(dev); | 1044 | pm_runtime_early_init(dev); |
1040 | INIT_LIST_HEAD(&dev->devres_head); | 1045 | INIT_LIST_HEAD(&dev->devres_head); |
1041 | list_add_tail(&dev->devres_head, | 1046 | list_add_tail(&dev->devres_head, |
1042 | &early_platform_device_list); | 1047 | &early_platform_device_list); |
1043 | } | 1048 | } |
1044 | } | 1049 | } |
1045 | } | 1050 | } |
1046 | 1051 | ||
1047 | /** | 1052 | /** |
1048 | * early_platform_driver_register_all - register early platform drivers | 1053 | * early_platform_driver_register_all - register early platform drivers |
1049 | * @class_str: string to identify early platform driver class | 1054 | * @class_str: string to identify early platform driver class |
1050 | * | 1055 | * |
1051 | * Used by architecture code to register all early platform drivers | 1056 | * Used by architecture code to register all early platform drivers |
1052 | * for a certain class. If omitted then only early platform drivers | 1057 | * for a certain class. If omitted then only early platform drivers |
1053 | * with matching kernel command line class parameters will be registered. | 1058 | * with matching kernel command line class parameters will be registered. |
1054 | */ | 1059 | */ |
1055 | void __init early_platform_driver_register_all(char *class_str) | 1060 | void __init early_platform_driver_register_all(char *class_str) |
1056 | { | 1061 | { |
1057 | /* The "class_str" parameter may or may not be present on the kernel | 1062 | /* The "class_str" parameter may or may not be present on the kernel |
1058 | * command line. If it is present then there may be more than one | 1063 | * command line. If it is present then there may be more than one |
1059 | * matching parameter. | 1064 | * matching parameter. |
1060 | * | 1065 | * |
1061 | * Since we register our early platform drivers using early_param() | 1066 | * Since we register our early platform drivers using early_param() |
1062 | * we need to make sure that they also get registered in the case | 1067 | * we need to make sure that they also get registered in the case |
1063 | * when the parameter is missing from the kernel command line. | 1068 | * when the parameter is missing from the kernel command line. |
1064 | * | 1069 | * |
1065 | * We use parse_early_options() to make sure the early_param() gets | 1070 | * We use parse_early_options() to make sure the early_param() gets |
1066 | * called at least once. The early_param() may be called more than | 1071 | * called at least once. The early_param() may be called more than |
1067 | * once since the name of the preferred device may be specified on | 1072 | * once since the name of the preferred device may be specified on |
1068 | * the kernel command line. early_platform_driver_register() handles | 1073 | * the kernel command line. early_platform_driver_register() handles |
1069 | * this case for us. | 1074 | * this case for us. |
1070 | */ | 1075 | */ |
1071 | parse_early_options(class_str); | 1076 | parse_early_options(class_str); |
1072 | } | 1077 | } |
1073 | 1078 | ||
1074 | /** | 1079 | /** |
1075 | * early_platform_match - find early platform device matching driver | 1080 | * early_platform_match - find early platform device matching driver |
1076 | * @epdrv: early platform driver structure | 1081 | * @epdrv: early platform driver structure |
1077 | * @id: id to match against | 1082 | * @id: id to match against |
1078 | */ | 1083 | */ |
1079 | static struct platform_device * __init | 1084 | static struct platform_device * __init |
1080 | early_platform_match(struct early_platform_driver *epdrv, int id) | 1085 | early_platform_match(struct early_platform_driver *epdrv, int id) |
1081 | { | 1086 | { |
1082 | struct platform_device *pd; | 1087 | struct platform_device *pd; |
1083 | 1088 | ||
1084 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) | 1089 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) |
1085 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) | 1090 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) |
1086 | if (pd->id == id) | 1091 | if (pd->id == id) |
1087 | return pd; | 1092 | return pd; |
1088 | 1093 | ||
1089 | return NULL; | 1094 | return NULL; |
1090 | } | 1095 | } |
1091 | 1096 | ||
1092 | /** | 1097 | /** |
1093 | * early_platform_left - check if early platform driver has matching devices | 1098 | * early_platform_left - check if early platform driver has matching devices |
1094 | * @epdrv: early platform driver structure | 1099 | * @epdrv: early platform driver structure |
1095 | * @id: return true if id or above exists | 1100 | * @id: return true if id or above exists |
1096 | */ | 1101 | */ |
1097 | static int __init early_platform_left(struct early_platform_driver *epdrv, | 1102 | static int __init early_platform_left(struct early_platform_driver *epdrv, |
1098 | int id) | 1103 | int id) |
1099 | { | 1104 | { |
1100 | struct platform_device *pd; | 1105 | struct platform_device *pd; |
1101 | 1106 | ||
1102 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) | 1107 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) |
1103 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) | 1108 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) |
1104 | if (pd->id >= id) | 1109 | if (pd->id >= id) |
1105 | return 1; | 1110 | return 1; |
1106 | 1111 | ||
1107 | return 0; | 1112 | return 0; |
1108 | } | 1113 | } |
1109 | 1114 | ||
1110 | /** | 1115 | /** |
1111 | * early_platform_driver_probe_id - probe drivers matching class_str and id | 1116 | * early_platform_driver_probe_id - probe drivers matching class_str and id |
1112 | * @class_str: string to identify early platform driver class | 1117 | * @class_str: string to identify early platform driver class |
1113 | * @id: id to match against | 1118 | * @id: id to match against |
1114 | * @nr_probe: number of platform devices to successfully probe before exiting | 1119 | * @nr_probe: number of platform devices to successfully probe before exiting |
1115 | */ | 1120 | */ |
1116 | static int __init early_platform_driver_probe_id(char *class_str, | 1121 | static int __init early_platform_driver_probe_id(char *class_str, |
1117 | int id, | 1122 | int id, |
1118 | int nr_probe) | 1123 | int nr_probe) |
1119 | { | 1124 | { |
1120 | struct early_platform_driver *epdrv; | 1125 | struct early_platform_driver *epdrv; |
1121 | struct platform_device *match; | 1126 | struct platform_device *match; |
1122 | int match_id; | 1127 | int match_id; |
1123 | int n = 0; | 1128 | int n = 0; |
1124 | int left = 0; | 1129 | int left = 0; |
1125 | 1130 | ||
1126 | list_for_each_entry(epdrv, &early_platform_driver_list, list) { | 1131 | list_for_each_entry(epdrv, &early_platform_driver_list, list) { |
1127 | /* only use drivers matching our class_str */ | 1132 | /* only use drivers matching our class_str */ |
1128 | if (strcmp(class_str, epdrv->class_str)) | 1133 | if (strcmp(class_str, epdrv->class_str)) |
1129 | continue; | 1134 | continue; |
1130 | 1135 | ||
1131 | if (id == -2) { | 1136 | if (id == -2) { |
1132 | match_id = epdrv->requested_id; | 1137 | match_id = epdrv->requested_id; |
1133 | left = 1; | 1138 | left = 1; |
1134 | 1139 | ||
1135 | } else { | 1140 | } else { |
1136 | match_id = id; | 1141 | match_id = id; |
1137 | left += early_platform_left(epdrv, id); | 1142 | left += early_platform_left(epdrv, id); |
1138 | 1143 | ||
1139 | /* skip requested id */ | 1144 | /* skip requested id */ |
1140 | switch (epdrv->requested_id) { | 1145 | switch (epdrv->requested_id) { |
1141 | case EARLY_PLATFORM_ID_ERROR: | 1146 | case EARLY_PLATFORM_ID_ERROR: |
1142 | case EARLY_PLATFORM_ID_UNSET: | 1147 | case EARLY_PLATFORM_ID_UNSET: |
1143 | break; | 1148 | break; |
1144 | default: | 1149 | default: |
1145 | if (epdrv->requested_id == id) | 1150 | if (epdrv->requested_id == id) |
1146 | match_id = EARLY_PLATFORM_ID_UNSET; | 1151 | match_id = EARLY_PLATFORM_ID_UNSET; |
1147 | } | 1152 | } |
1148 | } | 1153 | } |
1149 | 1154 | ||
1150 | switch (match_id) { | 1155 | switch (match_id) { |
1151 | case EARLY_PLATFORM_ID_ERROR: | 1156 | case EARLY_PLATFORM_ID_ERROR: |
1152 | pr_warn("%s: unable to parse %s parameter\n", | 1157 | pr_warn("%s: unable to parse %s parameter\n", |
1153 | class_str, epdrv->pdrv->driver.name); | 1158 | class_str, epdrv->pdrv->driver.name); |
1154 | /* fall-through */ | 1159 | /* fall-through */ |
1155 | case EARLY_PLATFORM_ID_UNSET: | 1160 | case EARLY_PLATFORM_ID_UNSET: |
1156 | match = NULL; | 1161 | match = NULL; |
1157 | break; | 1162 | break; |
1158 | default: | 1163 | default: |
1159 | match = early_platform_match(epdrv, match_id); | 1164 | match = early_platform_match(epdrv, match_id); |
1160 | } | 1165 | } |
1161 | 1166 | ||
1162 | if (match) { | 1167 | if (match) { |
1163 | /* | 1168 | /* |
1164 | * Set up a sensible init_name to enable | 1169 | * Set up a sensible init_name to enable |
1165 | * dev_name() and others to be used before the | 1170 | * dev_name() and others to be used before the |
1166 | * rest of the driver core is initialized. | 1171 | * rest of the driver core is initialized. |
1167 | */ | 1172 | */ |
1168 | if (!match->dev.init_name && slab_is_available()) { | 1173 | if (!match->dev.init_name && slab_is_available()) { |
1169 | if (match->id != -1) | 1174 | if (match->id != -1) |
1170 | match->dev.init_name = | 1175 | match->dev.init_name = |
1171 | kasprintf(GFP_KERNEL, "%s.%d", | 1176 | kasprintf(GFP_KERNEL, "%s.%d", |
1172 | match->name, | 1177 | match->name, |
1173 | match->id); | 1178 | match->id); |
1174 | else | 1179 | else |
1175 | match->dev.init_name = | 1180 | match->dev.init_name = |
1176 | kasprintf(GFP_KERNEL, "%s", | 1181 | kasprintf(GFP_KERNEL, "%s", |
1177 | match->name); | 1182 | match->name); |
1178 | 1183 | ||
1179 | if (!match->dev.init_name) | 1184 | if (!match->dev.init_name) |
1180 | return -ENOMEM; | 1185 | return -ENOMEM; |
1181 | } | 1186 | } |
1182 | 1187 | ||
1183 | if (epdrv->pdrv->probe(match)) | 1188 | if (epdrv->pdrv->probe(match)) |
1184 | pr_warn("%s: unable to probe %s early.\n", | 1189 | pr_warn("%s: unable to probe %s early.\n", |
1185 | class_str, match->name); | 1190 | class_str, match->name); |
1186 | else | 1191 | else |
1187 | n++; | 1192 | n++; |
1188 | } | 1193 | } |
1189 | 1194 | ||
1190 | if (n >= nr_probe) | 1195 | if (n >= nr_probe) |
1191 | break; | 1196 | break; |
1192 | } | 1197 | } |
1193 | 1198 | ||
1194 | if (left) | 1199 | if (left) |
1195 | return n; | 1200 | return n; |
1196 | else | 1201 | else |
1197 | return -ENODEV; | 1202 | return -ENODEV; |
1198 | } | 1203 | } |
1199 | 1204 | ||
1200 | /** | 1205 | /** |
1201 | * early_platform_driver_probe - probe a class of registered drivers | 1206 | * early_platform_driver_probe - probe a class of registered drivers |
1202 | * @class_str: string to identify early platform driver class | 1207 | * @class_str: string to identify early platform driver class |
1203 | * @nr_probe: number of platform devices to successfully probe before exiting | 1208 | * @nr_probe: number of platform devices to successfully probe before exiting |
1204 | * @user_only: only probe user specified early platform devices | 1209 | * @user_only: only probe user specified early platform devices |
1205 | * | 1210 | * |
1206 | * Used by architecture code to probe registered early platform drivers | 1211 | * Used by architecture code to probe registered early platform drivers |
1207 | * within a certain class. For probe to happen a registered early platform | 1212 | * within a certain class. For probe to happen a registered early platform |
1208 | * device matching a registered early platform driver is needed. | 1213 | * device matching a registered early platform driver is needed. |
1209 | */ | 1214 | */ |
1210 | int __init early_platform_driver_probe(char *class_str, | 1215 | int __init early_platform_driver_probe(char *class_str, |
1211 | int nr_probe, | 1216 | int nr_probe, |
1212 | int user_only) | 1217 | int user_only) |
1213 | { | 1218 | { |
1214 | int k, n, i; | 1219 | int k, n, i; |
1215 | 1220 | ||
1216 | n = 0; | 1221 | n = 0; |
1217 | for (i = -2; n < nr_probe; i++) { | 1222 | for (i = -2; n < nr_probe; i++) { |
1218 | k = early_platform_driver_probe_id(class_str, i, nr_probe - n); | 1223 | k = early_platform_driver_probe_id(class_str, i, nr_probe - n); |
1219 | 1224 | ||
1220 | if (k < 0) | 1225 | if (k < 0) |
1221 | break; | 1226 | break; |
1222 | 1227 | ||
1223 | n += k; | 1228 | n += k; |
1224 | 1229 | ||
1225 | if (user_only) | 1230 | if (user_only) |
1226 | break; | 1231 | break; |
1227 | } | 1232 | } |
1228 | 1233 | ||
1229 | return n; | 1234 | return n; |
1230 | } | 1235 | } |
1231 | 1236 | ||
1232 | /** | 1237 | /** |
1233 | * early_platform_cleanup - clean up early platform code | 1238 | * early_platform_cleanup - clean up early platform code |
1234 | */ | 1239 | */ |
1235 | void __init early_platform_cleanup(void) | 1240 | void __init early_platform_cleanup(void) |
1236 | { | 1241 | { |
1237 | struct platform_device *pd, *pd2; | 1242 | struct platform_device *pd, *pd2; |
1238 | 1243 | ||
1239 | /* clean up the devres list used to chain devices */ | 1244 | /* clean up the devres list used to chain devices */ |
1240 | list_for_each_entry_safe(pd, pd2, &early_platform_device_list, | 1245 | list_for_each_entry_safe(pd, pd2, &early_platform_device_list, |
1241 | dev.devres_head) { | 1246 | dev.devres_head) { |
1242 | list_del(&pd->dev.devres_head); | 1247 | list_del(&pd->dev.devres_head); |
1243 | memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); | 1248 | memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); |
1244 | } | 1249 | } |
1245 | } | 1250 | } |
1246 | 1251 | ||
1247 | 1252 |
drivers/of/irq.c
1 | /* | 1 | /* |
2 | * Derived from arch/i386/kernel/irq.c | 2 | * Derived from arch/i386/kernel/irq.c |
3 | * Copyright (C) 1992 Linus Torvalds | 3 | * Copyright (C) 1992 Linus Torvalds |
4 | * Adapted from arch/i386 by Gary Thomas | 4 | * Adapted from arch/i386 by Gary Thomas |
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
6 | * Updated and modified by Cort Dougan <cort@fsmlabs.com> | 6 | * Updated and modified by Cort Dougan <cort@fsmlabs.com> |
7 | * Copyright (C) 1996-2001 Cort Dougan | 7 | * Copyright (C) 1996-2001 Cort Dougan |
8 | * Adapted for Power Macintosh by Paul Mackerras | 8 | * Adapted for Power Macintosh by Paul Mackerras |
9 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) | 9 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
13 | * as published by the Free Software Foundation; either version | 13 | * as published by the Free Software Foundation; either version |
14 | * 2 of the License, or (at your option) any later version. | 14 | * 2 of the License, or (at your option) any later version. |
15 | * | 15 | * |
16 | * This file contains the code used to make IRQ descriptions in the | 16 | * This file contains the code used to make IRQ descriptions in the |
17 | * device tree to actual irq numbers on an interrupt controller | 17 | * device tree to actual irq numbers on an interrupt controller |
18 | * driver. | 18 | * driver. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
25 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space | 30 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space |
31 | * @dev: Device node of the device whose interrupt is to be mapped | 31 | * @dev: Device node of the device whose interrupt is to be mapped |
32 | * @index: Index of the interrupt to map | 32 | * @index: Index of the interrupt to map |
33 | * | 33 | * |
34 | * This function is a wrapper that chains of_irq_parse_one() and | 34 | * This function is a wrapper that chains of_irq_parse_one() and |
35 | * irq_create_of_mapping() to make things easier to callers | 35 | * irq_create_of_mapping() to make things easier to callers |
36 | */ | 36 | */ |
37 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | 37 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) |
38 | { | 38 | { |
39 | struct of_phandle_args oirq; | 39 | struct of_phandle_args oirq; |
40 | 40 | ||
41 | if (of_irq_parse_one(dev, index, &oirq)) | 41 | if (of_irq_parse_one(dev, index, &oirq)) |
42 | return 0; | 42 | return 0; |
43 | 43 | ||
44 | return irq_create_of_mapping(&oirq); | 44 | return irq_create_of_mapping(&oirq); |
45 | } | 45 | } |
46 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | 46 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * of_irq_find_parent - Given a device node, find its interrupt parent node | 49 | * of_irq_find_parent - Given a device node, find its interrupt parent node |
50 | * @child: pointer to device node | 50 | * @child: pointer to device node |
51 | * | 51 | * |
52 | * Returns a pointer to the interrupt parent node, or NULL if the interrupt | 52 | * Returns a pointer to the interrupt parent node, or NULL if the interrupt |
53 | * parent could not be determined. | 53 | * parent could not be determined. |
54 | */ | 54 | */ |
55 | struct device_node *of_irq_find_parent(struct device_node *child) | 55 | struct device_node *of_irq_find_parent(struct device_node *child) |
56 | { | 56 | { |
57 | struct device_node *p; | 57 | struct device_node *p; |
58 | const __be32 *parp; | 58 | const __be32 *parp; |
59 | 59 | ||
60 | if (!of_node_get(child)) | 60 | if (!of_node_get(child)) |
61 | return NULL; | 61 | return NULL; |
62 | 62 | ||
63 | do { | 63 | do { |
64 | parp = of_get_property(child, "interrupt-parent", NULL); | 64 | parp = of_get_property(child, "interrupt-parent", NULL); |
65 | if (parp == NULL) | 65 | if (parp == NULL) |
66 | p = of_get_parent(child); | 66 | p = of_get_parent(child); |
67 | else { | 67 | else { |
68 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | 68 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) |
69 | p = of_node_get(of_irq_dflt_pic); | 69 | p = of_node_get(of_irq_dflt_pic); |
70 | else | 70 | else |
71 | p = of_find_node_by_phandle(be32_to_cpup(parp)); | 71 | p = of_find_node_by_phandle(be32_to_cpup(parp)); |
72 | } | 72 | } |
73 | of_node_put(child); | 73 | of_node_put(child); |
74 | child = p; | 74 | child = p; |
75 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | 75 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); |
76 | 76 | ||
77 | return p; | 77 | return p; |
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
81 | * of_irq_parse_raw - Low level interrupt tree parsing | 81 | * of_irq_parse_raw - Low level interrupt tree parsing |
82 | * @parent: the device interrupt parent | 82 | * @parent: the device interrupt parent |
83 | * @addr: address specifier (start of "reg" property of the device) in be32 format | 83 | * @addr: address specifier (start of "reg" property of the device) in be32 format |
84 | * @out_irq: structure of_irq updated by this function | 84 | * @out_irq: structure of_irq updated by this function |
85 | * | 85 | * |
86 | * Returns 0 on success and a negative number on error | 86 | * Returns 0 on success and a negative number on error |
87 | * | 87 | * |
88 | * This function is a low-level interrupt tree walking function. It | 88 | * This function is a low-level interrupt tree walking function. It |
89 | * can be used to do a partial walk with synthetized reg and interrupts | 89 | * can be used to do a partial walk with synthetized reg and interrupts |
90 | * properties, for example when resolving PCI interrupts when no device | 90 | * properties, for example when resolving PCI interrupts when no device |
91 | * node exist for the parent. It takes an interrupt specifier structure as | 91 | * node exist for the parent. It takes an interrupt specifier structure as |
92 | * input, walks the tree looking for any interrupt-map properties, translates | 92 | * input, walks the tree looking for any interrupt-map properties, translates |
93 | * the specifier for each map, and then returns the translated map. | 93 | * the specifier for each map, and then returns the translated map. |
94 | */ | 94 | */ |
95 | int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) | 95 | int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) |
96 | { | 96 | { |
97 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; | 97 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; |
98 | __be32 initial_match_array[MAX_PHANDLE_ARGS]; | 98 | __be32 initial_match_array[MAX_PHANDLE_ARGS]; |
99 | const __be32 *match_array = initial_match_array; | 99 | const __be32 *match_array = initial_match_array; |
100 | const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; | 100 | const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; |
101 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; | 101 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; |
102 | int imaplen, match, i; | 102 | int imaplen, match, i; |
103 | 103 | ||
104 | #ifdef DEBUG | 104 | #ifdef DEBUG |
105 | of_print_phandle_args("of_irq_parse_raw: ", out_irq); | 105 | of_print_phandle_args("of_irq_parse_raw: ", out_irq); |
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | ipar = of_node_get(out_irq->np); | 108 | ipar = of_node_get(out_irq->np); |
109 | 109 | ||
110 | /* First get the #interrupt-cells property of the current cursor | 110 | /* First get the #interrupt-cells property of the current cursor |
111 | * that tells us how to interpret the passed-in intspec. If there | 111 | * that tells us how to interpret the passed-in intspec. If there |
112 | * is none, we are nice and just walk up the tree | 112 | * is none, we are nice and just walk up the tree |
113 | */ | 113 | */ |
114 | do { | 114 | do { |
115 | tmp = of_get_property(ipar, "#interrupt-cells", NULL); | 115 | tmp = of_get_property(ipar, "#interrupt-cells", NULL); |
116 | if (tmp != NULL) { | 116 | if (tmp != NULL) { |
117 | intsize = be32_to_cpu(*tmp); | 117 | intsize = be32_to_cpu(*tmp); |
118 | break; | 118 | break; |
119 | } | 119 | } |
120 | tnode = ipar; | 120 | tnode = ipar; |
121 | ipar = of_irq_find_parent(ipar); | 121 | ipar = of_irq_find_parent(ipar); |
122 | of_node_put(tnode); | 122 | of_node_put(tnode); |
123 | } while (ipar); | 123 | } while (ipar); |
124 | if (ipar == NULL) { | 124 | if (ipar == NULL) { |
125 | pr_debug(" -> no parent found !\n"); | 125 | pr_debug(" -> no parent found !\n"); |
126 | goto fail; | 126 | goto fail; |
127 | } | 127 | } |
128 | 128 | ||
129 | pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); | 129 | pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); |
130 | 130 | ||
131 | if (out_irq->args_count != intsize) | 131 | if (out_irq->args_count != intsize) |
132 | return -EINVAL; | 132 | return -EINVAL; |
133 | 133 | ||
134 | /* Look for this #address-cells. We have to implement the old linux | 134 | /* Look for this #address-cells. We have to implement the old linux |
135 | * trick of looking for the parent here as some device-trees rely on it | 135 | * trick of looking for the parent here as some device-trees rely on it |
136 | */ | 136 | */ |
137 | old = of_node_get(ipar); | 137 | old = of_node_get(ipar); |
138 | do { | 138 | do { |
139 | tmp = of_get_property(old, "#address-cells", NULL); | 139 | tmp = of_get_property(old, "#address-cells", NULL); |
140 | tnode = of_get_parent(old); | 140 | tnode = of_get_parent(old); |
141 | of_node_put(old); | 141 | of_node_put(old); |
142 | old = tnode; | 142 | old = tnode; |
143 | } while (old && tmp == NULL); | 143 | } while (old && tmp == NULL); |
144 | of_node_put(old); | 144 | of_node_put(old); |
145 | old = NULL; | 145 | old = NULL; |
146 | addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp); | 146 | addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp); |
147 | 147 | ||
148 | pr_debug(" -> addrsize=%d\n", addrsize); | 148 | pr_debug(" -> addrsize=%d\n", addrsize); |
149 | 149 | ||
150 | /* Range check so that the temporary buffer doesn't overflow */ | 150 | /* Range check so that the temporary buffer doesn't overflow */ |
151 | if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) | 151 | if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) |
152 | goto fail; | 152 | goto fail; |
153 | 153 | ||
154 | /* Precalculate the match array - this simplifies match loop */ | 154 | /* Precalculate the match array - this simplifies match loop */ |
155 | for (i = 0; i < addrsize; i++) | 155 | for (i = 0; i < addrsize; i++) |
156 | initial_match_array[i] = addr ? addr[i] : 0; | 156 | initial_match_array[i] = addr ? addr[i] : 0; |
157 | for (i = 0; i < intsize; i++) | 157 | for (i = 0; i < intsize; i++) |
158 | initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]); | 158 | initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]); |
159 | 159 | ||
160 | /* Now start the actual "proper" walk of the interrupt tree */ | 160 | /* Now start the actual "proper" walk of the interrupt tree */ |
161 | while (ipar != NULL) { | 161 | while (ipar != NULL) { |
162 | /* Now check if cursor is an interrupt-controller and if it is | 162 | /* Now check if cursor is an interrupt-controller and if it is |
163 | * then we are done | 163 | * then we are done |
164 | */ | 164 | */ |
165 | if (of_get_property(ipar, "interrupt-controller", NULL) != | 165 | if (of_get_property(ipar, "interrupt-controller", NULL) != |
166 | NULL) { | 166 | NULL) { |
167 | pr_debug(" -> got it !\n"); | 167 | pr_debug(" -> got it !\n"); |
168 | return 0; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * interrupt-map parsing does not work without a reg | 172 | * interrupt-map parsing does not work without a reg |
173 | * property when #address-cells != 0 | 173 | * property when #address-cells != 0 |
174 | */ | 174 | */ |
175 | if (addrsize && !addr) { | 175 | if (addrsize && !addr) { |
176 | pr_debug(" -> no reg passed in when needed !\n"); | 176 | pr_debug(" -> no reg passed in when needed !\n"); |
177 | goto fail; | 177 | goto fail; |
178 | } | 178 | } |
179 | 179 | ||
180 | /* Now look for an interrupt-map */ | 180 | /* Now look for an interrupt-map */ |
181 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | 181 | imap = of_get_property(ipar, "interrupt-map", &imaplen); |
182 | /* No interrupt map, check for an interrupt parent */ | 182 | /* No interrupt map, check for an interrupt parent */ |
183 | if (imap == NULL) { | 183 | if (imap == NULL) { |
184 | pr_debug(" -> no map, getting parent\n"); | 184 | pr_debug(" -> no map, getting parent\n"); |
185 | newpar = of_irq_find_parent(ipar); | 185 | newpar = of_irq_find_parent(ipar); |
186 | goto skiplevel; | 186 | goto skiplevel; |
187 | } | 187 | } |
188 | imaplen /= sizeof(u32); | 188 | imaplen /= sizeof(u32); |
189 | 189 | ||
190 | /* Look for a mask */ | 190 | /* Look for a mask */ |
191 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); | 191 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); |
192 | if (!imask) | 192 | if (!imask) |
193 | imask = dummy_imask; | 193 | imask = dummy_imask; |
194 | 194 | ||
195 | /* Parse interrupt-map */ | 195 | /* Parse interrupt-map */ |
196 | match = 0; | 196 | match = 0; |
197 | while (imaplen > (addrsize + intsize + 1) && !match) { | 197 | while (imaplen > (addrsize + intsize + 1) && !match) { |
198 | /* Compare specifiers */ | 198 | /* Compare specifiers */ |
199 | match = 1; | 199 | match = 1; |
200 | for (i = 0; i < (addrsize + intsize); i++, imaplen--) | 200 | for (i = 0; i < (addrsize + intsize); i++, imaplen--) |
201 | match &= !((match_array[i] ^ *imap++) & imask[i]); | 201 | match &= !((match_array[i] ^ *imap++) & imask[i]); |
202 | 202 | ||
203 | pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); | 203 | pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); |
204 | 204 | ||
205 | /* Get the interrupt parent */ | 205 | /* Get the interrupt parent */ |
206 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | 206 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) |
207 | newpar = of_node_get(of_irq_dflt_pic); | 207 | newpar = of_node_get(of_irq_dflt_pic); |
208 | else | 208 | else |
209 | newpar = of_find_node_by_phandle(be32_to_cpup(imap)); | 209 | newpar = of_find_node_by_phandle(be32_to_cpup(imap)); |
210 | imap++; | 210 | imap++; |
211 | --imaplen; | 211 | --imaplen; |
212 | 212 | ||
213 | /* Check if not found */ | 213 | /* Check if not found */ |
214 | if (newpar == NULL) { | 214 | if (newpar == NULL) { |
215 | pr_debug(" -> imap parent not found !\n"); | 215 | pr_debug(" -> imap parent not found !\n"); |
216 | goto fail; | 216 | goto fail; |
217 | } | 217 | } |
218 | 218 | ||
219 | if (!of_device_is_available(newpar)) | 219 | if (!of_device_is_available(newpar)) |
220 | match = 0; | 220 | match = 0; |
221 | 221 | ||
222 | /* Get #interrupt-cells and #address-cells of new | 222 | /* Get #interrupt-cells and #address-cells of new |
223 | * parent | 223 | * parent |
224 | */ | 224 | */ |
225 | tmp = of_get_property(newpar, "#interrupt-cells", NULL); | 225 | tmp = of_get_property(newpar, "#interrupt-cells", NULL); |
226 | if (tmp == NULL) { | 226 | if (tmp == NULL) { |
227 | pr_debug(" -> parent lacks #interrupt-cells!\n"); | 227 | pr_debug(" -> parent lacks #interrupt-cells!\n"); |
228 | goto fail; | 228 | goto fail; |
229 | } | 229 | } |
230 | newintsize = be32_to_cpu(*tmp); | 230 | newintsize = be32_to_cpu(*tmp); |
231 | tmp = of_get_property(newpar, "#address-cells", NULL); | 231 | tmp = of_get_property(newpar, "#address-cells", NULL); |
232 | newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp); | 232 | newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp); |
233 | 233 | ||
234 | pr_debug(" -> newintsize=%d, newaddrsize=%d\n", | 234 | pr_debug(" -> newintsize=%d, newaddrsize=%d\n", |
235 | newintsize, newaddrsize); | 235 | newintsize, newaddrsize); |
236 | 236 | ||
237 | /* Check for malformed properties */ | 237 | /* Check for malformed properties */ |
238 | if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)) | 238 | if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)) |
239 | goto fail; | 239 | goto fail; |
240 | if (imaplen < (newaddrsize + newintsize)) | 240 | if (imaplen < (newaddrsize + newintsize)) |
241 | goto fail; | 241 | goto fail; |
242 | 242 | ||
243 | imap += newaddrsize + newintsize; | 243 | imap += newaddrsize + newintsize; |
244 | imaplen -= newaddrsize + newintsize; | 244 | imaplen -= newaddrsize + newintsize; |
245 | 245 | ||
246 | pr_debug(" -> imaplen=%d\n", imaplen); | 246 | pr_debug(" -> imaplen=%d\n", imaplen); |
247 | } | 247 | } |
248 | if (!match) | 248 | if (!match) |
249 | goto fail; | 249 | goto fail; |
250 | 250 | ||
251 | /* | 251 | /* |
252 | * Successfully parsed an interrrupt-map translation; copy new | 252 | * Successfully parsed an interrrupt-map translation; copy new |
253 | * interrupt specifier into the out_irq structure | 253 | * interrupt specifier into the out_irq structure |
254 | */ | 254 | */ |
255 | out_irq->np = newpar; | 255 | out_irq->np = newpar; |
256 | 256 | ||
257 | match_array = imap - newaddrsize - newintsize; | 257 | match_array = imap - newaddrsize - newintsize; |
258 | for (i = 0; i < newintsize; i++) | 258 | for (i = 0; i < newintsize; i++) |
259 | out_irq->args[i] = be32_to_cpup(imap - newintsize + i); | 259 | out_irq->args[i] = be32_to_cpup(imap - newintsize + i); |
260 | out_irq->args_count = intsize = newintsize; | 260 | out_irq->args_count = intsize = newintsize; |
261 | addrsize = newaddrsize; | 261 | addrsize = newaddrsize; |
262 | 262 | ||
263 | skiplevel: | 263 | skiplevel: |
264 | /* Iterate again with new parent */ | 264 | /* Iterate again with new parent */ |
265 | pr_debug(" -> new parent: %s\n", of_node_full_name(newpar)); | 265 | pr_debug(" -> new parent: %s\n", of_node_full_name(newpar)); |
266 | of_node_put(ipar); | 266 | of_node_put(ipar); |
267 | ipar = newpar; | 267 | ipar = newpar; |
268 | newpar = NULL; | 268 | newpar = NULL; |
269 | } | 269 | } |
270 | fail: | 270 | fail: |
271 | of_node_put(ipar); | 271 | of_node_put(ipar); |
272 | of_node_put(newpar); | 272 | of_node_put(newpar); |
273 | 273 | ||
274 | return -EINVAL; | 274 | return -EINVAL; |
275 | } | 275 | } |
276 | EXPORT_SYMBOL_GPL(of_irq_parse_raw); | 276 | EXPORT_SYMBOL_GPL(of_irq_parse_raw); |
277 | 277 | ||
278 | /** | 278 | /** |
279 | * of_irq_parse_one - Resolve an interrupt for a device | 279 | * of_irq_parse_one - Resolve an interrupt for a device |
280 | * @device: the device whose interrupt is to be resolved | 280 | * @device: the device whose interrupt is to be resolved |
281 | * @index: index of the interrupt to resolve | 281 | * @index: index of the interrupt to resolve |
282 | * @out_irq: structure of_irq filled by this function | 282 | * @out_irq: structure of_irq filled by this function |
283 | * | 283 | * |
284 | * This function resolves an interrupt for a node by walking the interrupt tree, | 284 | * This function resolves an interrupt for a node by walking the interrupt tree, |
285 | * finding which interrupt controller node it is attached to, and returning the | 285 | * finding which interrupt controller node it is attached to, and returning the |
286 | * interrupt specifier that can be used to retrieve a Linux IRQ number. | 286 | * interrupt specifier that can be used to retrieve a Linux IRQ number. |
287 | */ | 287 | */ |
288 | int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) | 288 | int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) |
289 | { | 289 | { |
290 | struct device_node *p; | 290 | struct device_node *p; |
291 | const __be32 *intspec, *tmp, *addr; | 291 | const __be32 *intspec, *tmp, *addr; |
292 | u32 intsize, intlen; | 292 | u32 intsize, intlen; |
293 | int i, res = -EINVAL; | 293 | int i, res = -EINVAL; |
294 | 294 | ||
295 | pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); | 295 | pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); |
296 | 296 | ||
297 | /* OldWorld mac stuff is "special", handle out of line */ | 297 | /* OldWorld mac stuff is "special", handle out of line */ |
298 | if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) | 298 | if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) |
299 | return of_irq_parse_oldworld(device, index, out_irq); | 299 | return of_irq_parse_oldworld(device, index, out_irq); |
300 | 300 | ||
301 | /* Get the reg property (if any) */ | 301 | /* Get the reg property (if any) */ |
302 | addr = of_get_property(device, "reg", NULL); | 302 | addr = of_get_property(device, "reg", NULL); |
303 | 303 | ||
304 | /* Get the interrupts property */ | 304 | /* Get the interrupts property */ |
305 | intspec = of_get_property(device, "interrupts", &intlen); | 305 | intspec = of_get_property(device, "interrupts", &intlen); |
306 | if (intspec == NULL) { | 306 | if (intspec == NULL) { |
307 | /* Try the new-style interrupts-extended */ | 307 | /* Try the new-style interrupts-extended */ |
308 | res = of_parse_phandle_with_args(device, "interrupts-extended", | 308 | res = of_parse_phandle_with_args(device, "interrupts-extended", |
309 | "#interrupt-cells", index, out_irq); | 309 | "#interrupt-cells", index, out_irq); |
310 | if (res) | 310 | if (res) |
311 | return -EINVAL; | 311 | return -EINVAL; |
312 | return of_irq_parse_raw(addr, out_irq); | 312 | return of_irq_parse_raw(addr, out_irq); |
313 | } | 313 | } |
314 | intlen /= sizeof(*intspec); | 314 | intlen /= sizeof(*intspec); |
315 | 315 | ||
316 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); | 316 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); |
317 | 317 | ||
318 | /* Look for the interrupt parent. */ | 318 | /* Look for the interrupt parent. */ |
319 | p = of_irq_find_parent(device); | 319 | p = of_irq_find_parent(device); |
320 | if (p == NULL) | 320 | if (p == NULL) |
321 | return -EINVAL; | 321 | return -EINVAL; |
322 | 322 | ||
323 | /* Get size of interrupt specifier */ | 323 | /* Get size of interrupt specifier */ |
324 | tmp = of_get_property(p, "#interrupt-cells", NULL); | 324 | tmp = of_get_property(p, "#interrupt-cells", NULL); |
325 | if (tmp == NULL) | 325 | if (tmp == NULL) |
326 | goto out; | 326 | goto out; |
327 | intsize = be32_to_cpu(*tmp); | 327 | intsize = be32_to_cpu(*tmp); |
328 | 328 | ||
329 | pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); | 329 | pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); |
330 | 330 | ||
331 | /* Check index */ | 331 | /* Check index */ |
332 | if ((index + 1) * intsize > intlen) | 332 | if ((index + 1) * intsize > intlen) |
333 | goto out; | 333 | goto out; |
334 | 334 | ||
335 | /* Copy intspec into irq structure */ | 335 | /* Copy intspec into irq structure */ |
336 | intspec += index * intsize; | 336 | intspec += index * intsize; |
337 | out_irq->np = p; | 337 | out_irq->np = p; |
338 | out_irq->args_count = intsize; | 338 | out_irq->args_count = intsize; |
339 | for (i = 0; i < intsize; i++) | 339 | for (i = 0; i < intsize; i++) |
340 | out_irq->args[i] = be32_to_cpup(intspec++); | 340 | out_irq->args[i] = be32_to_cpup(intspec++); |
341 | 341 | ||
342 | /* Check if there are any interrupt-map translations to process */ | 342 | /* Check if there are any interrupt-map translations to process */ |
343 | res = of_irq_parse_raw(addr, out_irq); | 343 | res = of_irq_parse_raw(addr, out_irq); |
344 | out: | 344 | out: |
345 | of_node_put(p); | 345 | of_node_put(p); |
346 | return res; | 346 | return res; |
347 | } | 347 | } |
348 | EXPORT_SYMBOL_GPL(of_irq_parse_one); | 348 | EXPORT_SYMBOL_GPL(of_irq_parse_one); |
349 | 349 | ||
350 | /** | 350 | /** |
351 | * of_irq_to_resource - Decode a node's IRQ and return it as a resource | 351 | * of_irq_to_resource - Decode a node's IRQ and return it as a resource |
352 | * @dev: pointer to device tree node | 352 | * @dev: pointer to device tree node |
353 | * @index: zero-based index of the irq | 353 | * @index: zero-based index of the irq |
354 | * @r: pointer to resource structure to return result into. | 354 | * @r: pointer to resource structure to return result into. |
355 | */ | 355 | */ |
356 | int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | 356 | int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) |
357 | { | 357 | { |
358 | int irq = irq_of_parse_and_map(dev, index); | 358 | int irq = irq_of_parse_and_map(dev, index); |
359 | 359 | ||
360 | /* Only dereference the resource if both the | 360 | /* Only dereference the resource if both the |
361 | * resource and the irq are valid. */ | 361 | * resource and the irq are valid. */ |
362 | if (r && irq) { | 362 | if (r && irq) { |
363 | const char *name = NULL; | 363 | const char *name = NULL; |
364 | 364 | ||
365 | memset(r, 0, sizeof(*r)); | 365 | memset(r, 0, sizeof(*r)); |
366 | /* | 366 | /* |
367 | * Get optional "interrupts-names" property to add a name | 367 | * Get optional "interrupt-names" property to add a name |
368 | * to the resource. | 368 | * to the resource. |
369 | */ | 369 | */ |
370 | of_property_read_string_index(dev, "interrupt-names", index, | 370 | of_property_read_string_index(dev, "interrupt-names", index, |
371 | &name); | 371 | &name); |
372 | 372 | ||
373 | r->start = r->end = irq; | 373 | r->start = r->end = irq; |
374 | r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq)); | 374 | r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq)); |
375 | r->name = name ? name : of_node_full_name(dev); | 375 | r->name = name ? name : of_node_full_name(dev); |
376 | } | 376 | } |
377 | 377 | ||
378 | return irq; | 378 | return irq; |
379 | } | 379 | } |
380 | EXPORT_SYMBOL_GPL(of_irq_to_resource); | 380 | EXPORT_SYMBOL_GPL(of_irq_to_resource); |
381 | |||
382 | /** | ||
383 | * of_irq_get - Decode a node's IRQ and return it as a Linux irq number | ||
384 | * @dev: pointer to device tree node | ||
385 | * @index: zero-based index of the irq | ||
386 | * | ||
387 | * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain | ||
388 | * is not yet created. | ||
389 | * | ||
390 | */ | ||
391 | int of_irq_get(struct device_node *dev, int index) | ||
392 | { | ||
393 | int rc; | ||
394 | struct of_phandle_args oirq; | ||
395 | struct irq_domain *domain; | ||
396 | |||
397 | rc = of_irq_parse_one(dev, index, &oirq); | ||
398 | if (rc) | ||
399 | return rc; | ||
400 | |||
401 | domain = irq_find_host(oirq.np); | ||
402 | if (!domain) | ||
403 | return -EPROBE_DEFER; | ||
404 | |||
405 | return irq_create_of_mapping(&oirq); | ||
406 | } | ||
381 | 407 | ||
382 | /** | 408 | /** |
383 | * of_irq_count - Count the number of IRQs a node uses | 409 | * of_irq_count - Count the number of IRQs a node uses |
384 | * @dev: pointer to device tree node | 410 | * @dev: pointer to device tree node |
385 | */ | 411 | */ |
386 | int of_irq_count(struct device_node *dev) | 412 | int of_irq_count(struct device_node *dev) |
387 | { | 413 | { |
388 | struct of_phandle_args irq; | 414 | struct of_phandle_args irq; |
389 | int nr = 0; | 415 | int nr = 0; |
390 | 416 | ||
391 | while (of_irq_parse_one(dev, nr, &irq) == 0) | 417 | while (of_irq_parse_one(dev, nr, &irq) == 0) |
392 | nr++; | 418 | nr++; |
393 | 419 | ||
394 | return nr; | 420 | return nr; |
395 | } | 421 | } |
396 | 422 | ||
397 | /** | 423 | /** |
398 | * of_irq_to_resource_table - Fill in resource table with node's IRQ info | 424 | * of_irq_to_resource_table - Fill in resource table with node's IRQ info |
399 | * @dev: pointer to device tree node | 425 | * @dev: pointer to device tree node |
400 | * @res: array of resources to fill in | 426 | * @res: array of resources to fill in |
401 | * @nr_irqs: the number of IRQs (and upper bound for num of @res elements) | 427 | * @nr_irqs: the number of IRQs (and upper bound for num of @res elements) |
402 | * | 428 | * |
403 | * Returns the size of the filled in table (up to @nr_irqs). | 429 | * Returns the size of the filled in table (up to @nr_irqs). |
404 | */ | 430 | */ |
405 | int of_irq_to_resource_table(struct device_node *dev, struct resource *res, | 431 | int of_irq_to_resource_table(struct device_node *dev, struct resource *res, |
406 | int nr_irqs) | 432 | int nr_irqs) |
407 | { | 433 | { |
408 | int i; | 434 | int i; |
409 | 435 | ||
410 | for (i = 0; i < nr_irqs; i++, res++) | 436 | for (i = 0; i < nr_irqs; i++, res++) |
411 | if (!of_irq_to_resource(dev, i, res)) | 437 | if (!of_irq_to_resource(dev, i, res)) |
412 | break; | 438 | break; |
413 | 439 | ||
414 | return i; | 440 | return i; |
415 | } | 441 | } |
416 | EXPORT_SYMBOL_GPL(of_irq_to_resource_table); | 442 | EXPORT_SYMBOL_GPL(of_irq_to_resource_table); |
417 | 443 | ||
418 | struct intc_desc { | 444 | struct intc_desc { |
419 | struct list_head list; | 445 | struct list_head list; |
420 | struct device_node *dev; | 446 | struct device_node *dev; |
421 | struct device_node *interrupt_parent; | 447 | struct device_node *interrupt_parent; |
422 | }; | 448 | }; |
423 | 449 | ||
424 | /** | 450 | /** |
425 | * of_irq_init - Scan and init matching interrupt controllers in DT | 451 | * of_irq_init - Scan and init matching interrupt controllers in DT |
426 | * @matches: 0 terminated array of nodes to match and init function to call | 452 | * @matches: 0 terminated array of nodes to match and init function to call |
427 | * | 453 | * |
428 | * This function scans the device tree for matching interrupt controller nodes, | 454 | * This function scans the device tree for matching interrupt controller nodes, |
429 | * and calls their initialization functions in order with parents first. | 455 | * and calls their initialization functions in order with parents first. |
430 | */ | 456 | */ |
431 | void __init of_irq_init(const struct of_device_id *matches) | 457 | void __init of_irq_init(const struct of_device_id *matches) |
432 | { | 458 | { |
433 | struct device_node *np, *parent = NULL; | 459 | struct device_node *np, *parent = NULL; |
434 | struct intc_desc *desc, *temp_desc; | 460 | struct intc_desc *desc, *temp_desc; |
435 | struct list_head intc_desc_list, intc_parent_list; | 461 | struct list_head intc_desc_list, intc_parent_list; |
436 | 462 | ||
437 | INIT_LIST_HEAD(&intc_desc_list); | 463 | INIT_LIST_HEAD(&intc_desc_list); |
438 | INIT_LIST_HEAD(&intc_parent_list); | 464 | INIT_LIST_HEAD(&intc_parent_list); |
439 | 465 | ||
440 | for_each_matching_node(np, matches) { | 466 | for_each_matching_node(np, matches) { |
441 | if (!of_find_property(np, "interrupt-controller", NULL) || | 467 | if (!of_find_property(np, "interrupt-controller", NULL) || |
442 | !of_device_is_available(np)) | 468 | !of_device_is_available(np)) |
443 | continue; | 469 | continue; |
444 | /* | 470 | /* |
445 | * Here, we allocate and populate an intc_desc with the node | 471 | * Here, we allocate and populate an intc_desc with the node |
446 | * pointer, interrupt-parent device_node etc. | 472 | * pointer, interrupt-parent device_node etc. |
447 | */ | 473 | */ |
448 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); | 474 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); |
449 | if (WARN_ON(!desc)) | 475 | if (WARN_ON(!desc)) |
450 | goto err; | 476 | goto err; |
451 | 477 | ||
452 | desc->dev = np; | 478 | desc->dev = np; |
453 | desc->interrupt_parent = of_irq_find_parent(np); | 479 | desc->interrupt_parent = of_irq_find_parent(np); |
454 | if (desc->interrupt_parent == np) | 480 | if (desc->interrupt_parent == np) |
455 | desc->interrupt_parent = NULL; | 481 | desc->interrupt_parent = NULL; |
456 | list_add_tail(&desc->list, &intc_desc_list); | 482 | list_add_tail(&desc->list, &intc_desc_list); |
457 | } | 483 | } |
458 | 484 | ||
459 | /* | 485 | /* |
460 | * The root irq controller is the one without an interrupt-parent. | 486 | * The root irq controller is the one without an interrupt-parent. |
461 | * That one goes first, followed by the controllers that reference it, | 487 | * That one goes first, followed by the controllers that reference it, |
462 | * followed by the ones that reference the 2nd level controllers, etc. | 488 | * followed by the ones that reference the 2nd level controllers, etc. |
463 | */ | 489 | */ |
464 | while (!list_empty(&intc_desc_list)) { | 490 | while (!list_empty(&intc_desc_list)) { |
465 | /* | 491 | /* |
466 | * Process all controllers with the current 'parent'. | 492 | * Process all controllers with the current 'parent'. |
467 | * First pass will be looking for NULL as the parent. | 493 | * First pass will be looking for NULL as the parent. |
468 | * The assumption is that NULL parent means a root controller. | 494 | * The assumption is that NULL parent means a root controller. |
469 | */ | 495 | */ |
470 | list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { | 496 | list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { |
471 | const struct of_device_id *match; | 497 | const struct of_device_id *match; |
472 | int ret; | 498 | int ret; |
473 | of_irq_init_cb_t irq_init_cb; | 499 | of_irq_init_cb_t irq_init_cb; |
474 | 500 | ||
475 | if (desc->interrupt_parent != parent) | 501 | if (desc->interrupt_parent != parent) |
476 | continue; | 502 | continue; |
477 | 503 | ||
478 | list_del(&desc->list); | 504 | list_del(&desc->list); |
479 | match = of_match_node(matches, desc->dev); | 505 | match = of_match_node(matches, desc->dev); |
480 | if (WARN(!match->data, | 506 | if (WARN(!match->data, |
481 | "of_irq_init: no init function for %s\n", | 507 | "of_irq_init: no init function for %s\n", |
482 | match->compatible)) { | 508 | match->compatible)) { |
483 | kfree(desc); | 509 | kfree(desc); |
484 | continue; | 510 | continue; |
485 | } | 511 | } |
486 | 512 | ||
487 | pr_debug("of_irq_init: init %s @ %p, parent %p\n", | 513 | pr_debug("of_irq_init: init %s @ %p, parent %p\n", |
488 | match->compatible, | 514 | match->compatible, |
489 | desc->dev, desc->interrupt_parent); | 515 | desc->dev, desc->interrupt_parent); |
490 | irq_init_cb = (of_irq_init_cb_t)match->data; | 516 | irq_init_cb = (of_irq_init_cb_t)match->data; |
491 | ret = irq_init_cb(desc->dev, desc->interrupt_parent); | 517 | ret = irq_init_cb(desc->dev, desc->interrupt_parent); |
492 | if (ret) { | 518 | if (ret) { |
493 | kfree(desc); | 519 | kfree(desc); |
494 | continue; | 520 | continue; |
495 | } | 521 | } |
496 | 522 | ||
497 | /* | 523 | /* |
498 | * This one is now set up; add it to the parent list so | 524 | * This one is now set up; add it to the parent list so |
499 | * its children can get processed in a subsequent pass. | 525 | * its children can get processed in a subsequent pass. |
500 | */ | 526 | */ |
501 | list_add_tail(&desc->list, &intc_parent_list); | 527 | list_add_tail(&desc->list, &intc_parent_list); |
502 | } | 528 | } |
503 | 529 | ||
504 | /* Get the next pending parent that might have children */ | 530 | /* Get the next pending parent that might have children */ |
505 | desc = list_first_entry_or_null(&intc_parent_list, | 531 | desc = list_first_entry_or_null(&intc_parent_list, |
506 | typeof(*desc), list); | 532 | typeof(*desc), list); |
507 | if (!desc) { | 533 | if (!desc) { |
508 | pr_err("of_irq_init: children remain, but no parents\n"); | 534 | pr_err("of_irq_init: children remain, but no parents\n"); |
509 | break; | 535 | break; |
510 | } | 536 | } |
511 | list_del(&desc->list); | 537 | list_del(&desc->list); |
512 | parent = desc->dev; | 538 | parent = desc->dev; |
513 | kfree(desc); | 539 | kfree(desc); |
514 | } | 540 | } |
515 | 541 | ||
516 | list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) { | 542 | list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) { |
517 | list_del(&desc->list); | 543 | list_del(&desc->list); |
518 | kfree(desc); | 544 | kfree(desc); |
519 | } | 545 | } |
520 | err: | 546 | err: |
521 | list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { | 547 | list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { |
522 | list_del(&desc->list); | 548 | list_del(&desc->list); |
523 | kfree(desc); | 549 | kfree(desc); |
524 | } | 550 | } |
525 | } | 551 | } |
526 | 552 |
drivers/of/platform.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | 2 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. |
3 | * <benh@kernel.crashing.org> | 3 | * <benh@kernel.crashing.org> |
4 | * and Arnd Bergmann, IBM Corp. | 4 | * and Arnd Bergmann, IBM Corp. |
5 | * Merged from powerpc/kernel/of_platform.c and | 5 | * Merged from powerpc/kernel/of_platform.c and |
6 | * sparc{,64}/kernel/of_device.c by Stephen Rothwell | 6 | * sparc{,64}/kernel/of_device.c by Stephen Rothwell |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License | 9 | * modify it under the terms of the GNU General Public License |
10 | * as published by the Free Software Foundation; either version | 10 | * as published by the Free Software Foundation; either version |
11 | * 2 of the License, or (at your option) any later version. | 11 | * 2 of the License, or (at your option) any later version. |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/amba/bus.h> | 16 | #include <linux/amba/bus.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
21 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
23 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | 25 | ||
26 | const struct of_device_id of_default_bus_match_table[] = { | 26 | const struct of_device_id of_default_bus_match_table[] = { |
27 | { .compatible = "simple-bus", }, | 27 | { .compatible = "simple-bus", }, |
28 | #ifdef CONFIG_ARM_AMBA | 28 | #ifdef CONFIG_ARM_AMBA |
29 | { .compatible = "arm,amba-bus", }, | 29 | { .compatible = "arm,amba-bus", }, |
30 | #endif /* CONFIG_ARM_AMBA */ | 30 | #endif /* CONFIG_ARM_AMBA */ |
31 | {} /* Empty terminated list */ | 31 | {} /* Empty terminated list */ |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static int of_dev_node_match(struct device *dev, void *data) | 34 | static int of_dev_node_match(struct device *dev, void *data) |
35 | { | 35 | { |
36 | return dev->of_node == data; | 36 | return dev->of_node == data; |
37 | } | 37 | } |
38 | 38 | ||
39 | /** | 39 | /** |
40 | * of_find_device_by_node - Find the platform_device associated with a node | 40 | * of_find_device_by_node - Find the platform_device associated with a node |
41 | * @np: Pointer to device tree node | 41 | * @np: Pointer to device tree node |
42 | * | 42 | * |
43 | * Returns platform_device pointer, or NULL if not found | 43 | * Returns platform_device pointer, or NULL if not found |
44 | */ | 44 | */ |
45 | struct platform_device *of_find_device_by_node(struct device_node *np) | 45 | struct platform_device *of_find_device_by_node(struct device_node *np) |
46 | { | 46 | { |
47 | struct device *dev; | 47 | struct device *dev; |
48 | 48 | ||
49 | dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); | 49 | dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); |
50 | return dev ? to_platform_device(dev) : NULL; | 50 | return dev ? to_platform_device(dev) : NULL; |
51 | } | 51 | } |
52 | EXPORT_SYMBOL(of_find_device_by_node); | 52 | EXPORT_SYMBOL(of_find_device_by_node); |
53 | 53 | ||
54 | #if defined(CONFIG_PPC_DCR) | 54 | #if defined(CONFIG_PPC_DCR) |
55 | #include <asm/dcr.h> | 55 | #include <asm/dcr.h> |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | #ifdef CONFIG_OF_ADDRESS | 58 | #ifdef CONFIG_OF_ADDRESS |
59 | /* | 59 | /* |
60 | * The following routines scan a subtree and registers a device for | 60 | * The following routines scan a subtree and registers a device for |
61 | * each applicable node. | 61 | * each applicable node. |
62 | * | 62 | * |
63 | * Note: sparc doesn't use these routines because it has a different | 63 | * Note: sparc doesn't use these routines because it has a different |
64 | * mechanism for creating devices from device tree nodes. | 64 | * mechanism for creating devices from device tree nodes. |
65 | */ | 65 | */ |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * of_device_make_bus_id - Use the device node data to assign a unique name | 68 | * of_device_make_bus_id - Use the device node data to assign a unique name |
69 | * @dev: pointer to device structure that is linked to a device tree node | 69 | * @dev: pointer to device structure that is linked to a device tree node |
70 | * | 70 | * |
71 | * This routine will first try using either the dcr-reg or the reg property | 71 | * This routine will first try using either the dcr-reg or the reg property |
72 | * value to derive a unique name. As a last resort it will use the node | 72 | * value to derive a unique name. As a last resort it will use the node |
73 | * name followed by a unique number. | 73 | * name followed by a unique number. |
74 | */ | 74 | */ |
75 | void of_device_make_bus_id(struct device *dev) | 75 | void of_device_make_bus_id(struct device *dev) |
76 | { | 76 | { |
77 | static atomic_t bus_no_reg_magic; | 77 | static atomic_t bus_no_reg_magic; |
78 | struct device_node *node = dev->of_node; | 78 | struct device_node *node = dev->of_node; |
79 | const __be32 *reg; | 79 | const __be32 *reg; |
80 | u64 addr; | 80 | u64 addr; |
81 | const __be32 *addrp; | 81 | const __be32 *addrp; |
82 | int magic; | 82 | int magic; |
83 | 83 | ||
84 | #ifdef CONFIG_PPC_DCR | 84 | #ifdef CONFIG_PPC_DCR |
85 | /* | 85 | /* |
86 | * If it's a DCR based device, use 'd' for native DCRs | 86 | * If it's a DCR based device, use 'd' for native DCRs |
87 | * and 'D' for MMIO DCRs. | 87 | * and 'D' for MMIO DCRs. |
88 | */ | 88 | */ |
89 | reg = of_get_property(node, "dcr-reg", NULL); | 89 | reg = of_get_property(node, "dcr-reg", NULL); |
90 | if (reg) { | 90 | if (reg) { |
91 | #ifdef CONFIG_PPC_DCR_NATIVE | 91 | #ifdef CONFIG_PPC_DCR_NATIVE |
92 | dev_set_name(dev, "d%x.%s", *reg, node->name); | 92 | dev_set_name(dev, "d%x.%s", *reg, node->name); |
93 | #else /* CONFIG_PPC_DCR_NATIVE */ | 93 | #else /* CONFIG_PPC_DCR_NATIVE */ |
94 | u64 addr = of_translate_dcr_address(node, *reg, NULL); | 94 | u64 addr = of_translate_dcr_address(node, *reg, NULL); |
95 | if (addr != OF_BAD_ADDR) { | 95 | if (addr != OF_BAD_ADDR) { |
96 | dev_set_name(dev, "D%llx.%s", | 96 | dev_set_name(dev, "D%llx.%s", |
97 | (unsigned long long)addr, node->name); | 97 | (unsigned long long)addr, node->name); |
98 | return; | 98 | return; |
99 | } | 99 | } |
100 | #endif /* !CONFIG_PPC_DCR_NATIVE */ | 100 | #endif /* !CONFIG_PPC_DCR_NATIVE */ |
101 | } | 101 | } |
102 | #endif /* CONFIG_PPC_DCR */ | 102 | #endif /* CONFIG_PPC_DCR */ |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * For MMIO, get the physical address | 105 | * For MMIO, get the physical address |
106 | */ | 106 | */ |
107 | reg = of_get_property(node, "reg", NULL); | 107 | reg = of_get_property(node, "reg", NULL); |
108 | if (reg) { | 108 | if (reg) { |
109 | if (of_can_translate_address(node)) { | 109 | if (of_can_translate_address(node)) { |
110 | addr = of_translate_address(node, reg); | 110 | addr = of_translate_address(node, reg); |
111 | } else { | 111 | } else { |
112 | addrp = of_get_address(node, 0, NULL, NULL); | 112 | addrp = of_get_address(node, 0, NULL, NULL); |
113 | if (addrp) | 113 | if (addrp) |
114 | addr = of_read_number(addrp, 1); | 114 | addr = of_read_number(addrp, 1); |
115 | else | 115 | else |
116 | addr = OF_BAD_ADDR; | 116 | addr = OF_BAD_ADDR; |
117 | } | 117 | } |
118 | if (addr != OF_BAD_ADDR) { | 118 | if (addr != OF_BAD_ADDR) { |
119 | dev_set_name(dev, "%llx.%s", | 119 | dev_set_name(dev, "%llx.%s", |
120 | (unsigned long long)addr, node->name); | 120 | (unsigned long long)addr, node->name); |
121 | return; | 121 | return; |
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
125 | /* | 125 | /* |
126 | * No BusID, use the node name and add a globally incremented | 126 | * No BusID, use the node name and add a globally incremented |
127 | * counter (and pray...) | 127 | * counter (and pray...) |
128 | */ | 128 | */ |
129 | magic = atomic_add_return(1, &bus_no_reg_magic); | 129 | magic = atomic_add_return(1, &bus_no_reg_magic); |
130 | dev_set_name(dev, "%s.%d", node->name, magic - 1); | 130 | dev_set_name(dev, "%s.%d", node->name, magic - 1); |
131 | } | 131 | } |
132 | 132 | ||
133 | /** | 133 | /** |
134 | * of_device_alloc - Allocate and initialize an of_device | 134 | * of_device_alloc - Allocate and initialize an of_device |
135 | * @np: device node to assign to device | 135 | * @np: device node to assign to device |
136 | * @bus_id: Name to assign to the device. May be null to use default name. | 136 | * @bus_id: Name to assign to the device. May be null to use default name. |
137 | * @parent: Parent device. | 137 | * @parent: Parent device. |
138 | */ | 138 | */ |
139 | struct platform_device *of_device_alloc(struct device_node *np, | 139 | struct platform_device *of_device_alloc(struct device_node *np, |
140 | const char *bus_id, | 140 | const char *bus_id, |
141 | struct device *parent) | 141 | struct device *parent) |
142 | { | 142 | { |
143 | struct platform_device *dev; | 143 | struct platform_device *dev; |
144 | int rc, i, num_reg = 0, num_irq; | 144 | int rc, i, num_reg = 0, num_irq; |
145 | struct resource *res, temp_res; | 145 | struct resource *res, temp_res; |
146 | 146 | ||
147 | dev = platform_device_alloc("", -1); | 147 | dev = platform_device_alloc("", -1); |
148 | if (!dev) | 148 | if (!dev) |
149 | return NULL; | 149 | return NULL; |
150 | 150 | ||
151 | /* count the io and irq resources */ | 151 | /* count the io and irq resources */ |
152 | if (of_can_translate_address(np)) | 152 | if (of_can_translate_address(np)) |
153 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) | 153 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) |
154 | num_reg++; | 154 | num_reg++; |
155 | num_irq = of_irq_count(np); | 155 | num_irq = of_irq_count(np); |
156 | 156 | ||
157 | /* Populate the resource table */ | 157 | /* Populate the resource table */ |
158 | if (num_irq || num_reg) { | 158 | if (num_irq || num_reg) { |
159 | res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL); | 159 | res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL); |
160 | if (!res) { | 160 | if (!res) { |
161 | platform_device_put(dev); | 161 | platform_device_put(dev); |
162 | return NULL; | 162 | return NULL; |
163 | } | 163 | } |
164 | 164 | ||
165 | dev->num_resources = num_reg + num_irq; | 165 | dev->num_resources = num_reg + num_irq; |
166 | dev->resource = res; | 166 | dev->resource = res; |
167 | for (i = 0; i < num_reg; i++, res++) { | 167 | for (i = 0; i < num_reg; i++, res++) { |
168 | rc = of_address_to_resource(np, i, res); | 168 | rc = of_address_to_resource(np, i, res); |
169 | WARN_ON(rc); | 169 | WARN_ON(rc); |
170 | } | 170 | } |
171 | WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); | 171 | if (of_irq_to_resource_table(np, res, num_irq) != num_irq) |
172 | pr_debug("not all legacy IRQ resources mapped for %s\n", | ||
173 | np->name); | ||
172 | } | 174 | } |
173 | 175 | ||
174 | dev->dev.of_node = of_node_get(np); | 176 | dev->dev.of_node = of_node_get(np); |
175 | #if defined(CONFIG_MICROBLAZE) | 177 | #if defined(CONFIG_MICROBLAZE) |
176 | dev->dev.dma_mask = &dev->archdata.dma_mask; | 178 | dev->dev.dma_mask = &dev->archdata.dma_mask; |
177 | #endif | 179 | #endif |
178 | dev->dev.parent = parent; | 180 | dev->dev.parent = parent; |
179 | 181 | ||
180 | if (bus_id) | 182 | if (bus_id) |
181 | dev_set_name(&dev->dev, "%s", bus_id); | 183 | dev_set_name(&dev->dev, "%s", bus_id); |
182 | else | 184 | else |
183 | of_device_make_bus_id(&dev->dev); | 185 | of_device_make_bus_id(&dev->dev); |
184 | 186 | ||
185 | return dev; | 187 | return dev; |
186 | } | 188 | } |
187 | EXPORT_SYMBOL(of_device_alloc); | 189 | EXPORT_SYMBOL(of_device_alloc); |
188 | 190 | ||
189 | /** | 191 | /** |
190 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device | 192 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device |
191 | * @np: pointer to node to create device for | 193 | * @np: pointer to node to create device for |
192 | * @bus_id: name to assign device | 194 | * @bus_id: name to assign device |
193 | * @platform_data: pointer to populate platform_data pointer with | 195 | * @platform_data: pointer to populate platform_data pointer with |
194 | * @parent: Linux device model parent device. | 196 | * @parent: Linux device model parent device. |
195 | * | 197 | * |
196 | * Returns pointer to created platform device, or NULL if a device was not | 198 | * Returns pointer to created platform device, or NULL if a device was not |
197 | * registered. Unavailable devices will not get registered. | 199 | * registered. Unavailable devices will not get registered. |
198 | */ | 200 | */ |
199 | static struct platform_device *of_platform_device_create_pdata( | 201 | static struct platform_device *of_platform_device_create_pdata( |
200 | struct device_node *np, | 202 | struct device_node *np, |
201 | const char *bus_id, | 203 | const char *bus_id, |
202 | void *platform_data, | 204 | void *platform_data, |
203 | struct device *parent) | 205 | struct device *parent) |
204 | { | 206 | { |
205 | struct platform_device *dev; | 207 | struct platform_device *dev; |
206 | 208 | ||
207 | if (!of_device_is_available(np)) | 209 | if (!of_device_is_available(np)) |
208 | return NULL; | 210 | return NULL; |
209 | 211 | ||
210 | dev = of_device_alloc(np, bus_id, parent); | 212 | dev = of_device_alloc(np, bus_id, parent); |
211 | if (!dev) | 213 | if (!dev) |
212 | return NULL; | 214 | return NULL; |
213 | 215 | ||
214 | #if defined(CONFIG_MICROBLAZE) | 216 | #if defined(CONFIG_MICROBLAZE) |
215 | dev->archdata.dma_mask = 0xffffffffUL; | 217 | dev->archdata.dma_mask = 0xffffffffUL; |
216 | #endif | 218 | #endif |
217 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | 219 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
218 | if (!dev->dev.dma_mask) | 220 | if (!dev->dev.dma_mask) |
219 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; | 221 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; |
220 | dev->dev.bus = &platform_bus_type; | 222 | dev->dev.bus = &platform_bus_type; |
221 | dev->dev.platform_data = platform_data; | 223 | dev->dev.platform_data = platform_data; |
222 | 224 | ||
223 | /* We do not fill the DMA ops for platform devices by default. | 225 | /* We do not fill the DMA ops for platform devices by default. |
224 | * This is currently the responsibility of the platform code | 226 | * This is currently the responsibility of the platform code |
225 | * to do such, possibly using a device notifier | 227 | * to do such, possibly using a device notifier |
226 | */ | 228 | */ |
227 | 229 | ||
228 | if (of_device_add(dev) != 0) { | 230 | if (of_device_add(dev) != 0) { |
229 | platform_device_put(dev); | 231 | platform_device_put(dev); |
230 | return NULL; | 232 | return NULL; |
231 | } | 233 | } |
232 | 234 | ||
233 | return dev; | 235 | return dev; |
234 | } | 236 | } |
235 | 237 | ||
236 | /** | 238 | /** |
237 | * of_platform_device_create - Alloc, initialize and register an of_device | 239 | * of_platform_device_create - Alloc, initialize and register an of_device |
238 | * @np: pointer to node to create device for | 240 | * @np: pointer to node to create device for |
239 | * @bus_id: name to assign device | 241 | * @bus_id: name to assign device |
240 | * @parent: Linux device model parent device. | 242 | * @parent: Linux device model parent device. |
241 | * | 243 | * |
242 | * Returns pointer to created platform device, or NULL if a device was not | 244 | * Returns pointer to created platform device, or NULL if a device was not |
243 | * registered. Unavailable devices will not get registered. | 245 | * registered. Unavailable devices will not get registered. |
244 | */ | 246 | */ |
245 | struct platform_device *of_platform_device_create(struct device_node *np, | 247 | struct platform_device *of_platform_device_create(struct device_node *np, |
246 | const char *bus_id, | 248 | const char *bus_id, |
247 | struct device *parent) | 249 | struct device *parent) |
248 | { | 250 | { |
249 | return of_platform_device_create_pdata(np, bus_id, NULL, parent); | 251 | return of_platform_device_create_pdata(np, bus_id, NULL, parent); |
250 | } | 252 | } |
251 | EXPORT_SYMBOL(of_platform_device_create); | 253 | EXPORT_SYMBOL(of_platform_device_create); |
252 | 254 | ||
253 | #ifdef CONFIG_ARM_AMBA | 255 | #ifdef CONFIG_ARM_AMBA |
254 | static struct amba_device *of_amba_device_create(struct device_node *node, | 256 | static struct amba_device *of_amba_device_create(struct device_node *node, |
255 | const char *bus_id, | 257 | const char *bus_id, |
256 | void *platform_data, | 258 | void *platform_data, |
257 | struct device *parent) | 259 | struct device *parent) |
258 | { | 260 | { |
259 | struct amba_device *dev; | 261 | struct amba_device *dev; |
260 | const void *prop; | 262 | const void *prop; |
261 | int i, ret; | 263 | int i, ret; |
262 | 264 | ||
263 | pr_debug("Creating amba device %s\n", node->full_name); | 265 | pr_debug("Creating amba device %s\n", node->full_name); |
264 | 266 | ||
265 | if (!of_device_is_available(node)) | 267 | if (!of_device_is_available(node)) |
266 | return NULL; | 268 | return NULL; |
267 | 269 | ||
268 | dev = amba_device_alloc(NULL, 0, 0); | 270 | dev = amba_device_alloc(NULL, 0, 0); |
269 | if (!dev) { | 271 | if (!dev) { |
270 | pr_err("%s(): amba_device_alloc() failed for %s\n", | 272 | pr_err("%s(): amba_device_alloc() failed for %s\n", |
271 | __func__, node->full_name); | 273 | __func__, node->full_name); |
272 | return NULL; | 274 | return NULL; |
273 | } | 275 | } |
274 | 276 | ||
275 | /* setup generic device info */ | 277 | /* setup generic device info */ |
276 | dev->dev.coherent_dma_mask = ~0; | 278 | dev->dev.coherent_dma_mask = ~0; |
277 | dev->dev.of_node = of_node_get(node); | 279 | dev->dev.of_node = of_node_get(node); |
278 | dev->dev.parent = parent; | 280 | dev->dev.parent = parent; |
279 | dev->dev.platform_data = platform_data; | 281 | dev->dev.platform_data = platform_data; |
280 | if (bus_id) | 282 | if (bus_id) |
281 | dev_set_name(&dev->dev, "%s", bus_id); | 283 | dev_set_name(&dev->dev, "%s", bus_id); |
282 | else | 284 | else |
283 | of_device_make_bus_id(&dev->dev); | 285 | of_device_make_bus_id(&dev->dev); |
284 | 286 | ||
285 | /* Allow the HW Peripheral ID to be overridden */ | 287 | /* Allow the HW Peripheral ID to be overridden */ |
286 | prop = of_get_property(node, "arm,primecell-periphid", NULL); | 288 | prop = of_get_property(node, "arm,primecell-periphid", NULL); |
287 | if (prop) | 289 | if (prop) |
288 | dev->periphid = of_read_ulong(prop, 1); | 290 | dev->periphid = of_read_ulong(prop, 1); |
289 | 291 | ||
290 | /* Decode the IRQs and address ranges */ | 292 | /* Decode the IRQs and address ranges */ |
291 | for (i = 0; i < AMBA_NR_IRQS; i++) | 293 | for (i = 0; i < AMBA_NR_IRQS; i++) |
292 | dev->irq[i] = irq_of_parse_and_map(node, i); | 294 | dev->irq[i] = irq_of_parse_and_map(node, i); |
293 | 295 | ||
294 | ret = of_address_to_resource(node, 0, &dev->res); | 296 | ret = of_address_to_resource(node, 0, &dev->res); |
295 | if (ret) { | 297 | if (ret) { |
296 | pr_err("%s(): of_address_to_resource() failed (%d) for %s\n", | 298 | pr_err("%s(): of_address_to_resource() failed (%d) for %s\n", |
297 | __func__, ret, node->full_name); | 299 | __func__, ret, node->full_name); |
298 | goto err_free; | 300 | goto err_free; |
299 | } | 301 | } |
300 | 302 | ||
301 | ret = amba_device_add(dev, &iomem_resource); | 303 | ret = amba_device_add(dev, &iomem_resource); |
302 | if (ret) { | 304 | if (ret) { |
303 | pr_err("%s(): amba_device_add() failed (%d) for %s\n", | 305 | pr_err("%s(): amba_device_add() failed (%d) for %s\n", |
304 | __func__, ret, node->full_name); | 306 | __func__, ret, node->full_name); |
305 | goto err_free; | 307 | goto err_free; |
306 | } | 308 | } |
307 | 309 | ||
308 | return dev; | 310 | return dev; |
309 | 311 | ||
310 | err_free: | 312 | err_free: |
311 | amba_device_put(dev); | 313 | amba_device_put(dev); |
312 | return NULL; | 314 | return NULL; |
313 | } | 315 | } |
314 | #else /* CONFIG_ARM_AMBA */ | 316 | #else /* CONFIG_ARM_AMBA */ |
315 | static struct amba_device *of_amba_device_create(struct device_node *node, | 317 | static struct amba_device *of_amba_device_create(struct device_node *node, |
316 | const char *bus_id, | 318 | const char *bus_id, |
317 | void *platform_data, | 319 | void *platform_data, |
318 | struct device *parent) | 320 | struct device *parent) |
319 | { | 321 | { |
320 | return NULL; | 322 | return NULL; |
321 | } | 323 | } |
322 | #endif /* CONFIG_ARM_AMBA */ | 324 | #endif /* CONFIG_ARM_AMBA */ |
323 | 325 | ||
324 | /** | 326 | /** |
325 | * of_devname_lookup() - Given a device node, lookup the preferred Linux name | 327 | * of_devname_lookup() - Given a device node, lookup the preferred Linux name |
326 | */ | 328 | */ |
327 | static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup, | 329 | static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup, |
328 | struct device_node *np) | 330 | struct device_node *np) |
329 | { | 331 | { |
330 | struct resource res; | 332 | struct resource res; |
331 | 333 | ||
332 | if (!lookup) | 334 | if (!lookup) |
333 | return NULL; | 335 | return NULL; |
334 | 336 | ||
335 | for(; lookup->compatible != NULL; lookup++) { | 337 | for(; lookup->compatible != NULL; lookup++) { |
336 | if (!of_device_is_compatible(np, lookup->compatible)) | 338 | if (!of_device_is_compatible(np, lookup->compatible)) |
337 | continue; | 339 | continue; |
338 | if (!of_address_to_resource(np, 0, &res)) | 340 | if (!of_address_to_resource(np, 0, &res)) |
339 | if (res.start != lookup->phys_addr) | 341 | if (res.start != lookup->phys_addr) |
340 | continue; | 342 | continue; |
341 | pr_debug("%s: devname=%s\n", np->full_name, lookup->name); | 343 | pr_debug("%s: devname=%s\n", np->full_name, lookup->name); |
342 | return lookup; | 344 | return lookup; |
343 | } | 345 | } |
344 | 346 | ||
345 | return NULL; | 347 | return NULL; |
346 | } | 348 | } |
347 | 349 | ||
348 | /** | 350 | /** |
349 | * of_platform_bus_create() - Create a device for a node and its children. | 351 | * of_platform_bus_create() - Create a device for a node and its children. |
350 | * @bus: device node of the bus to instantiate | 352 | * @bus: device node of the bus to instantiate |
351 | * @matches: match table for bus nodes | 353 | * @matches: match table for bus nodes |
352 | * @lookup: auxdata table for matching id and platform_data with device nodes | 354 | * @lookup: auxdata table for matching id and platform_data with device nodes |
353 | * @parent: parent for new device, or NULL for top level. | 355 | * @parent: parent for new device, or NULL for top level. |
354 | * @strict: require compatible property | 356 | * @strict: require compatible property |
355 | * | 357 | * |
356 | * Creates a platform_device for the provided device_node, and optionally | 358 | * Creates a platform_device for the provided device_node, and optionally |
357 | * recursively create devices for all the child nodes. | 359 | * recursively create devices for all the child nodes. |
358 | */ | 360 | */ |
359 | static int of_platform_bus_create(struct device_node *bus, | 361 | static int of_platform_bus_create(struct device_node *bus, |
360 | const struct of_device_id *matches, | 362 | const struct of_device_id *matches, |
361 | const struct of_dev_auxdata *lookup, | 363 | const struct of_dev_auxdata *lookup, |
362 | struct device *parent, bool strict) | 364 | struct device *parent, bool strict) |
363 | { | 365 | { |
364 | const struct of_dev_auxdata *auxdata; | 366 | const struct of_dev_auxdata *auxdata; |
365 | struct device_node *child; | 367 | struct device_node *child; |
366 | struct platform_device *dev; | 368 | struct platform_device *dev; |
367 | const char *bus_id = NULL; | 369 | const char *bus_id = NULL; |
368 | void *platform_data = NULL; | 370 | void *platform_data = NULL; |
369 | int rc = 0; | 371 | int rc = 0; |
370 | 372 | ||
371 | /* Make sure it has a compatible property */ | 373 | /* Make sure it has a compatible property */ |
372 | if (strict && (!of_get_property(bus, "compatible", NULL))) { | 374 | if (strict && (!of_get_property(bus, "compatible", NULL))) { |
373 | pr_debug("%s() - skipping %s, no compatible prop\n", | 375 | pr_debug("%s() - skipping %s, no compatible prop\n", |
374 | __func__, bus->full_name); | 376 | __func__, bus->full_name); |
375 | return 0; | 377 | return 0; |
376 | } | 378 | } |
377 | 379 | ||
378 | auxdata = of_dev_lookup(lookup, bus); | 380 | auxdata = of_dev_lookup(lookup, bus); |
379 | if (auxdata) { | 381 | if (auxdata) { |
380 | bus_id = auxdata->name; | 382 | bus_id = auxdata->name; |
381 | platform_data = auxdata->platform_data; | 383 | platform_data = auxdata->platform_data; |
382 | } | 384 | } |
383 | 385 | ||
384 | if (of_device_is_compatible(bus, "arm,primecell")) { | 386 | if (of_device_is_compatible(bus, "arm,primecell")) { |
385 | /* | 387 | /* |
386 | * Don't return an error here to keep compatibility with older | 388 | * Don't return an error here to keep compatibility with older |
387 | * device tree files. | 389 | * device tree files. |
388 | */ | 390 | */ |
389 | of_amba_device_create(bus, bus_id, platform_data, parent); | 391 | of_amba_device_create(bus, bus_id, platform_data, parent); |
390 | return 0; | 392 | return 0; |
391 | } | 393 | } |
392 | 394 | ||
393 | dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent); | 395 | dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent); |
394 | if (!dev || !of_match_node(matches, bus)) | 396 | if (!dev || !of_match_node(matches, bus)) |
395 | return 0; | 397 | return 0; |
396 | 398 | ||
397 | for_each_child_of_node(bus, child) { | 399 | for_each_child_of_node(bus, child) { |
398 | pr_debug(" create child: %s\n", child->full_name); | 400 | pr_debug(" create child: %s\n", child->full_name); |
399 | rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict); | 401 | rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict); |
400 | if (rc) { | 402 | if (rc) { |
401 | of_node_put(child); | 403 | of_node_put(child); |
402 | break; | 404 | break; |
403 | } | 405 | } |
404 | } | 406 | } |
405 | return rc; | 407 | return rc; |
406 | } | 408 | } |
407 | 409 | ||
408 | /** | 410 | /** |
409 | * of_platform_bus_probe() - Probe the device-tree for platform buses | 411 | * of_platform_bus_probe() - Probe the device-tree for platform buses |
410 | * @root: parent of the first level to probe or NULL for the root of the tree | 412 | * @root: parent of the first level to probe or NULL for the root of the tree |
411 | * @matches: match table for bus nodes | 413 | * @matches: match table for bus nodes |
412 | * @parent: parent to hook devices from, NULL for toplevel | 414 | * @parent: parent to hook devices from, NULL for toplevel |
413 | * | 415 | * |
414 | * Note that children of the provided root are not instantiated as devices | 416 | * Note that children of the provided root are not instantiated as devices |
415 | * unless the specified root itself matches the bus list and is not NULL. | 417 | * unless the specified root itself matches the bus list and is not NULL. |
416 | */ | 418 | */ |
417 | int of_platform_bus_probe(struct device_node *root, | 419 | int of_platform_bus_probe(struct device_node *root, |
418 | const struct of_device_id *matches, | 420 | const struct of_device_id *matches, |
419 | struct device *parent) | 421 | struct device *parent) |
420 | { | 422 | { |
421 | struct device_node *child; | 423 | struct device_node *child; |
422 | int rc = 0; | 424 | int rc = 0; |
423 | 425 | ||
424 | root = root ? of_node_get(root) : of_find_node_by_path("/"); | 426 | root = root ? of_node_get(root) : of_find_node_by_path("/"); |
425 | if (!root) | 427 | if (!root) |
426 | return -EINVAL; | 428 | return -EINVAL; |
427 | 429 | ||
428 | pr_debug("of_platform_bus_probe()\n"); | 430 | pr_debug("of_platform_bus_probe()\n"); |
429 | pr_debug(" starting at: %s\n", root->full_name); | 431 | pr_debug(" starting at: %s\n", root->full_name); |
430 | 432 | ||
431 | /* Do a self check of bus type, if there's a match, create children */ | 433 | /* Do a self check of bus type, if there's a match, create children */ |
432 | if (of_match_node(matches, root)) { | 434 | if (of_match_node(matches, root)) { |
433 | rc = of_platform_bus_create(root, matches, NULL, parent, false); | 435 | rc = of_platform_bus_create(root, matches, NULL, parent, false); |
434 | } else for_each_child_of_node(root, child) { | 436 | } else for_each_child_of_node(root, child) { |
435 | if (!of_match_node(matches, child)) | 437 | if (!of_match_node(matches, child)) |
436 | continue; | 438 | continue; |
437 | rc = of_platform_bus_create(child, matches, NULL, parent, false); | 439 | rc = of_platform_bus_create(child, matches, NULL, parent, false); |
438 | if (rc) | 440 | if (rc) |
439 | break; | 441 | break; |
440 | } | 442 | } |
441 | 443 | ||
442 | of_node_put(root); | 444 | of_node_put(root); |
443 | return rc; | 445 | return rc; |
444 | } | 446 | } |
445 | EXPORT_SYMBOL(of_platform_bus_probe); | 447 | EXPORT_SYMBOL(of_platform_bus_probe); |
446 | 448 | ||
447 | /** | 449 | /** |
448 | * of_platform_populate() - Populate platform_devices from device tree data | 450 | * of_platform_populate() - Populate platform_devices from device tree data |
449 | * @root: parent of the first level to probe or NULL for the root of the tree | 451 | * @root: parent of the first level to probe or NULL for the root of the tree |
450 | * @matches: match table, NULL to use the default | 452 | * @matches: match table, NULL to use the default |
451 | * @lookup: auxdata table for matching id and platform_data with device nodes | 453 | * @lookup: auxdata table for matching id and platform_data with device nodes |
452 | * @parent: parent to hook devices from, NULL for toplevel | 454 | * @parent: parent to hook devices from, NULL for toplevel |
453 | * | 455 | * |
454 | * Similar to of_platform_bus_probe(), this function walks the device tree | 456 | * Similar to of_platform_bus_probe(), this function walks the device tree |
455 | * and creates devices from nodes. It differs in that it follows the modern | 457 | * and creates devices from nodes. It differs in that it follows the modern |
456 | * convention of requiring all device nodes to have a 'compatible' property, | 458 | * convention of requiring all device nodes to have a 'compatible' property, |
457 | * and it is suitable for creating devices which are children of the root | 459 | * and it is suitable for creating devices which are children of the root |
458 | * node (of_platform_bus_probe will only create children of the root which | 460 | * node (of_platform_bus_probe will only create children of the root which |
459 | * are selected by the @matches argument). | 461 | * are selected by the @matches argument). |
460 | * | 462 | * |
461 | * New board support should be using this function instead of | 463 | * New board support should be using this function instead of |
462 | * of_platform_bus_probe(). | 464 | * of_platform_bus_probe(). |
463 | * | 465 | * |
464 | * Returns 0 on success, < 0 on failure. | 466 | * Returns 0 on success, < 0 on failure. |
465 | */ | 467 | */ |
466 | int of_platform_populate(struct device_node *root, | 468 | int of_platform_populate(struct device_node *root, |
467 | const struct of_device_id *matches, | 469 | const struct of_device_id *matches, |
468 | const struct of_dev_auxdata *lookup, | 470 | const struct of_dev_auxdata *lookup, |
469 | struct device *parent) | 471 | struct device *parent) |
470 | { | 472 | { |
471 | struct device_node *child; | 473 | struct device_node *child; |
472 | int rc = 0; | 474 | int rc = 0; |
473 | 475 | ||
474 | root = root ? of_node_get(root) : of_find_node_by_path("/"); | 476 | root = root ? of_node_get(root) : of_find_node_by_path("/"); |
475 | if (!root) | 477 | if (!root) |
476 | return -EINVAL; | 478 | return -EINVAL; |
477 | 479 | ||
478 | for_each_child_of_node(root, child) { | 480 | for_each_child_of_node(root, child) { |
479 | rc = of_platform_bus_create(child, matches, lookup, parent, true); | 481 | rc = of_platform_bus_create(child, matches, lookup, parent, true); |
480 | if (rc) | 482 | if (rc) |
481 | break; | 483 | break; |
482 | } | 484 | } |
483 | 485 | ||
484 | of_node_put(root); | 486 | of_node_put(root); |
485 | return rc; | 487 | return rc; |
486 | } | 488 | } |
487 | EXPORT_SYMBOL_GPL(of_platform_populate); | 489 | EXPORT_SYMBOL_GPL(of_platform_populate); |
488 | #endif /* CONFIG_OF_ADDRESS */ | 490 | #endif /* CONFIG_OF_ADDRESS */ |
489 | 491 |
drivers/of/selftest.c
1 | /* | 1 | /* |
2 | * Self tests for device tree subsystem | 2 | * Self tests for device tree subsystem |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #define pr_fmt(fmt) "### dt-test ### " fmt | 5 | #define pr_fmt(fmt) "### dt-test ### " fmt |
6 | 6 | ||
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | #include <linux/err.h> | 8 | #include <linux/err.h> |
9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <linux/of_irq.h> | 12 | #include <linux/of_irq.h> |
13 | #include <linux/of_platform.h> | ||
13 | #include <linux/list.h> | 14 | #include <linux/list.h> |
14 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
16 | #include <linux/device.h> | 17 | #include <linux/device.h> |
17 | 18 | ||
18 | static struct selftest_results { | 19 | static struct selftest_results { |
19 | int passed; | 20 | int passed; |
20 | int failed; | 21 | int failed; |
21 | } selftest_results; | 22 | } selftest_results; |
22 | 23 | ||
23 | #define selftest(result, fmt, ...) { \ | 24 | #define selftest(result, fmt, ...) { \ |
24 | if (!(result)) { \ | 25 | if (!(result)) { \ |
25 | selftest_results.failed++; \ | 26 | selftest_results.failed++; \ |
26 | pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ | 27 | pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ |
27 | } else { \ | 28 | } else { \ |
28 | selftest_results.passed++; \ | 29 | selftest_results.passed++; \ |
29 | pr_debug("pass %s():%i\n", __func__, __LINE__); \ | 30 | pr_debug("pass %s():%i\n", __func__, __LINE__); \ |
30 | } \ | 31 | } \ |
31 | } | 32 | } |
32 | 33 | ||
33 | static void __init of_selftest_dynamic(void) | 34 | static void __init of_selftest_dynamic(void) |
34 | { | 35 | { |
35 | struct device_node *np; | 36 | struct device_node *np; |
36 | struct property *prop; | 37 | struct property *prop; |
37 | 38 | ||
38 | np = of_find_node_by_path("/testcase-data"); | 39 | np = of_find_node_by_path("/testcase-data"); |
39 | if (!np) { | 40 | if (!np) { |
40 | pr_err("missing testcase data\n"); | 41 | pr_err("missing testcase data\n"); |
41 | return; | 42 | return; |
42 | } | 43 | } |
43 | 44 | ||
44 | /* Array of 4 properties for the purpose of testing */ | 45 | /* Array of 4 properties for the purpose of testing */ |
45 | prop = kzalloc(sizeof(*prop) * 4, GFP_KERNEL); | 46 | prop = kzalloc(sizeof(*prop) * 4, GFP_KERNEL); |
46 | if (!prop) { | 47 | if (!prop) { |
47 | selftest(0, "kzalloc() failed\n"); | 48 | selftest(0, "kzalloc() failed\n"); |
48 | return; | 49 | return; |
49 | } | 50 | } |
50 | 51 | ||
51 | /* Add a new property - should pass*/ | 52 | /* Add a new property - should pass*/ |
52 | prop->name = "new-property"; | 53 | prop->name = "new-property"; |
53 | prop->value = "new-property-data"; | 54 | prop->value = "new-property-data"; |
54 | prop->length = strlen(prop->value); | 55 | prop->length = strlen(prop->value); |
55 | selftest(of_add_property(np, prop) == 0, "Adding a new property failed\n"); | 56 | selftest(of_add_property(np, prop) == 0, "Adding a new property failed\n"); |
56 | 57 | ||
57 | /* Try to add an existing property - should fail */ | 58 | /* Try to add an existing property - should fail */ |
58 | prop++; | 59 | prop++; |
59 | prop->name = "new-property"; | 60 | prop->name = "new-property"; |
60 | prop->value = "new-property-data-should-fail"; | 61 | prop->value = "new-property-data-should-fail"; |
61 | prop->length = strlen(prop->value); | 62 | prop->length = strlen(prop->value); |
62 | selftest(of_add_property(np, prop) != 0, | 63 | selftest(of_add_property(np, prop) != 0, |
63 | "Adding an existing property should have failed\n"); | 64 | "Adding an existing property should have failed\n"); |
64 | 65 | ||
65 | /* Try to modify an existing property - should pass */ | 66 | /* Try to modify an existing property - should pass */ |
66 | prop->value = "modify-property-data-should-pass"; | 67 | prop->value = "modify-property-data-should-pass"; |
67 | prop->length = strlen(prop->value); | 68 | prop->length = strlen(prop->value); |
68 | selftest(of_update_property(np, prop) == 0, | 69 | selftest(of_update_property(np, prop) == 0, |
69 | "Updating an existing property should have passed\n"); | 70 | "Updating an existing property should have passed\n"); |
70 | 71 | ||
71 | /* Try to modify non-existent property - should pass*/ | 72 | /* Try to modify non-existent property - should pass*/ |
72 | prop++; | 73 | prop++; |
73 | prop->name = "modify-property"; | 74 | prop->name = "modify-property"; |
74 | prop->value = "modify-missing-property-data-should-pass"; | 75 | prop->value = "modify-missing-property-data-should-pass"; |
75 | prop->length = strlen(prop->value); | 76 | prop->length = strlen(prop->value); |
76 | selftest(of_update_property(np, prop) == 0, | 77 | selftest(of_update_property(np, prop) == 0, |
77 | "Updating a missing property should have passed\n"); | 78 | "Updating a missing property should have passed\n"); |
78 | 79 | ||
79 | /* Remove property - should pass */ | 80 | /* Remove property - should pass */ |
80 | selftest(of_remove_property(np, prop) == 0, | 81 | selftest(of_remove_property(np, prop) == 0, |
81 | "Removing a property should have passed\n"); | 82 | "Removing a property should have passed\n"); |
82 | 83 | ||
83 | /* Adding very large property - should pass */ | 84 | /* Adding very large property - should pass */ |
84 | prop++; | 85 | prop++; |
85 | prop->name = "large-property-PAGE_SIZEx8"; | 86 | prop->name = "large-property-PAGE_SIZEx8"; |
86 | prop->length = PAGE_SIZE * 8; | 87 | prop->length = PAGE_SIZE * 8; |
87 | prop->value = kzalloc(prop->length, GFP_KERNEL); | 88 | prop->value = kzalloc(prop->length, GFP_KERNEL); |
88 | selftest(prop->value != NULL, "Unable to allocate large buffer\n"); | 89 | selftest(prop->value != NULL, "Unable to allocate large buffer\n"); |
89 | if (prop->value) | 90 | if (prop->value) |
90 | selftest(of_add_property(np, prop) == 0, | 91 | selftest(of_add_property(np, prop) == 0, |
91 | "Adding a large property should have passed\n"); | 92 | "Adding a large property should have passed\n"); |
92 | } | 93 | } |
93 | 94 | ||
94 | static void __init of_selftest_parse_phandle_with_args(void) | 95 | static void __init of_selftest_parse_phandle_with_args(void) |
95 | { | 96 | { |
96 | struct device_node *np; | 97 | struct device_node *np; |
97 | struct of_phandle_args args; | 98 | struct of_phandle_args args; |
98 | int i, rc; | 99 | int i, rc; |
99 | 100 | ||
100 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | 101 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); |
101 | if (!np) { | 102 | if (!np) { |
102 | pr_err("missing testcase data\n"); | 103 | pr_err("missing testcase data\n"); |
103 | return; | 104 | return; |
104 | } | 105 | } |
105 | 106 | ||
106 | rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); | 107 | rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); |
107 | selftest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); | 108 | selftest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); |
108 | 109 | ||
109 | for (i = 0; i < 8; i++) { | 110 | for (i = 0; i < 8; i++) { |
110 | bool passed = true; | 111 | bool passed = true; |
111 | rc = of_parse_phandle_with_args(np, "phandle-list", | 112 | rc = of_parse_phandle_with_args(np, "phandle-list", |
112 | "#phandle-cells", i, &args); | 113 | "#phandle-cells", i, &args); |
113 | 114 | ||
114 | /* Test the values from tests-phandle.dtsi */ | 115 | /* Test the values from tests-phandle.dtsi */ |
115 | switch (i) { | 116 | switch (i) { |
116 | case 0: | 117 | case 0: |
117 | passed &= !rc; | 118 | passed &= !rc; |
118 | passed &= (args.args_count == 1); | 119 | passed &= (args.args_count == 1); |
119 | passed &= (args.args[0] == (i + 1)); | 120 | passed &= (args.args[0] == (i + 1)); |
120 | break; | 121 | break; |
121 | case 1: | 122 | case 1: |
122 | passed &= !rc; | 123 | passed &= !rc; |
123 | passed &= (args.args_count == 2); | 124 | passed &= (args.args_count == 2); |
124 | passed &= (args.args[0] == (i + 1)); | 125 | passed &= (args.args[0] == (i + 1)); |
125 | passed &= (args.args[1] == 0); | 126 | passed &= (args.args[1] == 0); |
126 | break; | 127 | break; |
127 | case 2: | 128 | case 2: |
128 | passed &= (rc == -ENOENT); | 129 | passed &= (rc == -ENOENT); |
129 | break; | 130 | break; |
130 | case 3: | 131 | case 3: |
131 | passed &= !rc; | 132 | passed &= !rc; |
132 | passed &= (args.args_count == 3); | 133 | passed &= (args.args_count == 3); |
133 | passed &= (args.args[0] == (i + 1)); | 134 | passed &= (args.args[0] == (i + 1)); |
134 | passed &= (args.args[1] == 4); | 135 | passed &= (args.args[1] == 4); |
135 | passed &= (args.args[2] == 3); | 136 | passed &= (args.args[2] == 3); |
136 | break; | 137 | break; |
137 | case 4: | 138 | case 4: |
138 | passed &= !rc; | 139 | passed &= !rc; |
139 | passed &= (args.args_count == 2); | 140 | passed &= (args.args_count == 2); |
140 | passed &= (args.args[0] == (i + 1)); | 141 | passed &= (args.args[0] == (i + 1)); |
141 | passed &= (args.args[1] == 100); | 142 | passed &= (args.args[1] == 100); |
142 | break; | 143 | break; |
143 | case 5: | 144 | case 5: |
144 | passed &= !rc; | 145 | passed &= !rc; |
145 | passed &= (args.args_count == 0); | 146 | passed &= (args.args_count == 0); |
146 | break; | 147 | break; |
147 | case 6: | 148 | case 6: |
148 | passed &= !rc; | 149 | passed &= !rc; |
149 | passed &= (args.args_count == 1); | 150 | passed &= (args.args_count == 1); |
150 | passed &= (args.args[0] == (i + 1)); | 151 | passed &= (args.args[0] == (i + 1)); |
151 | break; | 152 | break; |
152 | case 7: | 153 | case 7: |
153 | passed &= (rc == -ENOENT); | 154 | passed &= (rc == -ENOENT); |
154 | break; | 155 | break; |
155 | default: | 156 | default: |
156 | passed = false; | 157 | passed = false; |
157 | } | 158 | } |
158 | 159 | ||
159 | selftest(passed, "index %i - data error on node %s rc=%i\n", | 160 | selftest(passed, "index %i - data error on node %s rc=%i\n", |
160 | i, args.np->full_name, rc); | 161 | i, args.np->full_name, rc); |
161 | } | 162 | } |
162 | 163 | ||
163 | /* Check for missing list property */ | 164 | /* Check for missing list property */ |
164 | rc = of_parse_phandle_with_args(np, "phandle-list-missing", | 165 | rc = of_parse_phandle_with_args(np, "phandle-list-missing", |
165 | "#phandle-cells", 0, &args); | 166 | "#phandle-cells", 0, &args); |
166 | selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc); | 167 | selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc); |
167 | rc = of_count_phandle_with_args(np, "phandle-list-missing", | 168 | rc = of_count_phandle_with_args(np, "phandle-list-missing", |
168 | "#phandle-cells"); | 169 | "#phandle-cells"); |
169 | selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc); | 170 | selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc); |
170 | 171 | ||
171 | /* Check for missing cells property */ | 172 | /* Check for missing cells property */ |
172 | rc = of_parse_phandle_with_args(np, "phandle-list", | 173 | rc = of_parse_phandle_with_args(np, "phandle-list", |
173 | "#phandle-cells-missing", 0, &args); | 174 | "#phandle-cells-missing", 0, &args); |
174 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); | 175 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
175 | rc = of_count_phandle_with_args(np, "phandle-list", | 176 | rc = of_count_phandle_with_args(np, "phandle-list", |
176 | "#phandle-cells-missing"); | 177 | "#phandle-cells-missing"); |
177 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); | 178 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
178 | 179 | ||
179 | /* Check for bad phandle in list */ | 180 | /* Check for bad phandle in list */ |
180 | rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle", | 181 | rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle", |
181 | "#phandle-cells", 0, &args); | 182 | "#phandle-cells", 0, &args); |
182 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); | 183 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
183 | rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle", | 184 | rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle", |
184 | "#phandle-cells"); | 185 | "#phandle-cells"); |
185 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); | 186 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
186 | 187 | ||
187 | /* Check for incorrectly formed argument list */ | 188 | /* Check for incorrectly formed argument list */ |
188 | rc = of_parse_phandle_with_args(np, "phandle-list-bad-args", | 189 | rc = of_parse_phandle_with_args(np, "phandle-list-bad-args", |
189 | "#phandle-cells", 1, &args); | 190 | "#phandle-cells", 1, &args); |
190 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); | 191 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
191 | rc = of_count_phandle_with_args(np, "phandle-list-bad-args", | 192 | rc = of_count_phandle_with_args(np, "phandle-list-bad-args", |
192 | "#phandle-cells"); | 193 | "#phandle-cells"); |
193 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); | 194 | selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); |
194 | } | 195 | } |
195 | 196 | ||
196 | static void __init of_selftest_property_match_string(void) | 197 | static void __init of_selftest_property_match_string(void) |
197 | { | 198 | { |
198 | struct device_node *np; | 199 | struct device_node *np; |
199 | int rc; | 200 | int rc; |
200 | 201 | ||
201 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | 202 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); |
202 | if (!np) { | 203 | if (!np) { |
203 | pr_err("No testcase data in device tree\n"); | 204 | pr_err("No testcase data in device tree\n"); |
204 | return; | 205 | return; |
205 | } | 206 | } |
206 | 207 | ||
207 | rc = of_property_match_string(np, "phandle-list-names", "first"); | 208 | rc = of_property_match_string(np, "phandle-list-names", "first"); |
208 | selftest(rc == 0, "first expected:0 got:%i\n", rc); | 209 | selftest(rc == 0, "first expected:0 got:%i\n", rc); |
209 | rc = of_property_match_string(np, "phandle-list-names", "second"); | 210 | rc = of_property_match_string(np, "phandle-list-names", "second"); |
210 | selftest(rc == 1, "second expected:0 got:%i\n", rc); | 211 | selftest(rc == 1, "second expected:0 got:%i\n", rc); |
211 | rc = of_property_match_string(np, "phandle-list-names", "third"); | 212 | rc = of_property_match_string(np, "phandle-list-names", "third"); |
212 | selftest(rc == 2, "third expected:0 got:%i\n", rc); | 213 | selftest(rc == 2, "third expected:0 got:%i\n", rc); |
213 | rc = of_property_match_string(np, "phandle-list-names", "fourth"); | 214 | rc = of_property_match_string(np, "phandle-list-names", "fourth"); |
214 | selftest(rc == -ENODATA, "unmatched string; rc=%i", rc); | 215 | selftest(rc == -ENODATA, "unmatched string; rc=%i", rc); |
215 | rc = of_property_match_string(np, "missing-property", "blah"); | 216 | rc = of_property_match_string(np, "missing-property", "blah"); |
216 | selftest(rc == -EINVAL, "missing property; rc=%i", rc); | 217 | selftest(rc == -EINVAL, "missing property; rc=%i", rc); |
217 | rc = of_property_match_string(np, "empty-property", "blah"); | 218 | rc = of_property_match_string(np, "empty-property", "blah"); |
218 | selftest(rc == -ENODATA, "empty property; rc=%i", rc); | 219 | selftest(rc == -ENODATA, "empty property; rc=%i", rc); |
219 | rc = of_property_match_string(np, "unterminated-string", "blah"); | 220 | rc = of_property_match_string(np, "unterminated-string", "blah"); |
220 | selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); | 221 | selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); |
221 | } | 222 | } |
222 | 223 | ||
223 | static void __init of_selftest_parse_interrupts(void) | 224 | static void __init of_selftest_parse_interrupts(void) |
224 | { | 225 | { |
225 | struct device_node *np; | 226 | struct device_node *np; |
226 | struct of_phandle_args args; | 227 | struct of_phandle_args args; |
227 | int i, rc; | 228 | int i, rc; |
228 | 229 | ||
229 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts0"); | 230 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts0"); |
230 | if (!np) { | 231 | if (!np) { |
231 | pr_err("missing testcase data\n"); | 232 | pr_err("missing testcase data\n"); |
232 | return; | 233 | return; |
233 | } | 234 | } |
234 | 235 | ||
235 | for (i = 0; i < 4; i++) { | 236 | for (i = 0; i < 4; i++) { |
236 | bool passed = true; | 237 | bool passed = true; |
237 | args.args_count = 0; | 238 | args.args_count = 0; |
238 | rc = of_irq_parse_one(np, i, &args); | 239 | rc = of_irq_parse_one(np, i, &args); |
239 | 240 | ||
240 | passed &= !rc; | 241 | passed &= !rc; |
241 | passed &= (args.args_count == 1); | 242 | passed &= (args.args_count == 1); |
242 | passed &= (args.args[0] == (i + 1)); | 243 | passed &= (args.args[0] == (i + 1)); |
243 | 244 | ||
244 | selftest(passed, "index %i - data error on node %s rc=%i\n", | 245 | selftest(passed, "index %i - data error on node %s rc=%i\n", |
245 | i, args.np->full_name, rc); | 246 | i, args.np->full_name, rc); |
246 | } | 247 | } |
247 | of_node_put(np); | 248 | of_node_put(np); |
248 | 249 | ||
249 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts1"); | 250 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts1"); |
250 | if (!np) { | 251 | if (!np) { |
251 | pr_err("missing testcase data\n"); | 252 | pr_err("missing testcase data\n"); |
252 | return; | 253 | return; |
253 | } | 254 | } |
254 | 255 | ||
255 | for (i = 0; i < 4; i++) { | 256 | for (i = 0; i < 4; i++) { |
256 | bool passed = true; | 257 | bool passed = true; |
257 | args.args_count = 0; | 258 | args.args_count = 0; |
258 | rc = of_irq_parse_one(np, i, &args); | 259 | rc = of_irq_parse_one(np, i, &args); |
259 | 260 | ||
260 | /* Test the values from tests-phandle.dtsi */ | 261 | /* Test the values from tests-phandle.dtsi */ |
261 | switch (i) { | 262 | switch (i) { |
262 | case 0: | 263 | case 0: |
263 | passed &= !rc; | 264 | passed &= !rc; |
264 | passed &= (args.args_count == 1); | 265 | passed &= (args.args_count == 1); |
265 | passed &= (args.args[0] == 9); | 266 | passed &= (args.args[0] == 9); |
266 | break; | 267 | break; |
267 | case 1: | 268 | case 1: |
268 | passed &= !rc; | 269 | passed &= !rc; |
269 | passed &= (args.args_count == 3); | 270 | passed &= (args.args_count == 3); |
270 | passed &= (args.args[0] == 10); | 271 | passed &= (args.args[0] == 10); |
271 | passed &= (args.args[1] == 11); | 272 | passed &= (args.args[1] == 11); |
272 | passed &= (args.args[2] == 12); | 273 | passed &= (args.args[2] == 12); |
273 | break; | 274 | break; |
274 | case 2: | 275 | case 2: |
275 | passed &= !rc; | 276 | passed &= !rc; |
276 | passed &= (args.args_count == 2); | 277 | passed &= (args.args_count == 2); |
277 | passed &= (args.args[0] == 13); | 278 | passed &= (args.args[0] == 13); |
278 | passed &= (args.args[1] == 14); | 279 | passed &= (args.args[1] == 14); |
279 | break; | 280 | break; |
280 | case 3: | 281 | case 3: |
281 | passed &= !rc; | 282 | passed &= !rc; |
282 | passed &= (args.args_count == 2); | 283 | passed &= (args.args_count == 2); |
283 | passed &= (args.args[0] == 15); | 284 | passed &= (args.args[0] == 15); |
284 | passed &= (args.args[1] == 16); | 285 | passed &= (args.args[1] == 16); |
285 | break; | 286 | break; |
286 | default: | 287 | default: |
287 | passed = false; | 288 | passed = false; |
288 | } | 289 | } |
289 | selftest(passed, "index %i - data error on node %s rc=%i\n", | 290 | selftest(passed, "index %i - data error on node %s rc=%i\n", |
290 | i, args.np->full_name, rc); | 291 | i, args.np->full_name, rc); |
291 | } | 292 | } |
292 | of_node_put(np); | 293 | of_node_put(np); |
293 | } | 294 | } |
294 | 295 | ||
295 | static void __init of_selftest_parse_interrupts_extended(void) | 296 | static void __init of_selftest_parse_interrupts_extended(void) |
296 | { | 297 | { |
297 | struct device_node *np; | 298 | struct device_node *np; |
298 | struct of_phandle_args args; | 299 | struct of_phandle_args args; |
299 | int i, rc; | 300 | int i, rc; |
300 | 301 | ||
301 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); | 302 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); |
302 | if (!np) { | 303 | if (!np) { |
303 | pr_err("missing testcase data\n"); | 304 | pr_err("missing testcase data\n"); |
304 | return; | 305 | return; |
305 | } | 306 | } |
306 | 307 | ||
307 | for (i = 0; i < 7; i++) { | 308 | for (i = 0; i < 7; i++) { |
308 | bool passed = true; | 309 | bool passed = true; |
309 | rc = of_irq_parse_one(np, i, &args); | 310 | rc = of_irq_parse_one(np, i, &args); |
310 | 311 | ||
311 | /* Test the values from tests-phandle.dtsi */ | 312 | /* Test the values from tests-phandle.dtsi */ |
312 | switch (i) { | 313 | switch (i) { |
313 | case 0: | 314 | case 0: |
314 | passed &= !rc; | 315 | passed &= !rc; |
315 | passed &= (args.args_count == 1); | 316 | passed &= (args.args_count == 1); |
316 | passed &= (args.args[0] == 1); | 317 | passed &= (args.args[0] == 1); |
317 | break; | 318 | break; |
318 | case 1: | 319 | case 1: |
319 | passed &= !rc; | 320 | passed &= !rc; |
320 | passed &= (args.args_count == 3); | 321 | passed &= (args.args_count == 3); |
321 | passed &= (args.args[0] == 2); | 322 | passed &= (args.args[0] == 2); |
322 | passed &= (args.args[1] == 3); | 323 | passed &= (args.args[1] == 3); |
323 | passed &= (args.args[2] == 4); | 324 | passed &= (args.args[2] == 4); |
324 | break; | 325 | break; |
325 | case 2: | 326 | case 2: |
326 | passed &= !rc; | 327 | passed &= !rc; |
327 | passed &= (args.args_count == 2); | 328 | passed &= (args.args_count == 2); |
328 | passed &= (args.args[0] == 5); | 329 | passed &= (args.args[0] == 5); |
329 | passed &= (args.args[1] == 6); | 330 | passed &= (args.args[1] == 6); |
330 | break; | 331 | break; |
331 | case 3: | 332 | case 3: |
332 | passed &= !rc; | 333 | passed &= !rc; |
333 | passed &= (args.args_count == 1); | 334 | passed &= (args.args_count == 1); |
334 | passed &= (args.args[0] == 9); | 335 | passed &= (args.args[0] == 9); |
335 | break; | 336 | break; |
336 | case 4: | 337 | case 4: |
337 | passed &= !rc; | 338 | passed &= !rc; |
338 | passed &= (args.args_count == 3); | 339 | passed &= (args.args_count == 3); |
339 | passed &= (args.args[0] == 10); | 340 | passed &= (args.args[0] == 10); |
340 | passed &= (args.args[1] == 11); | 341 | passed &= (args.args[1] == 11); |
341 | passed &= (args.args[2] == 12); | 342 | passed &= (args.args[2] == 12); |
342 | break; | 343 | break; |
343 | case 5: | 344 | case 5: |
344 | passed &= !rc; | 345 | passed &= !rc; |
345 | passed &= (args.args_count == 2); | 346 | passed &= (args.args_count == 2); |
346 | passed &= (args.args[0] == 13); | 347 | passed &= (args.args[0] == 13); |
347 | passed &= (args.args[1] == 14); | 348 | passed &= (args.args[1] == 14); |
348 | break; | 349 | break; |
349 | case 6: | 350 | case 6: |
350 | passed &= !rc; | 351 | passed &= !rc; |
351 | passed &= (args.args_count == 1); | 352 | passed &= (args.args_count == 1); |
352 | passed &= (args.args[0] == 15); | 353 | passed &= (args.args[0] == 15); |
353 | break; | 354 | break; |
354 | default: | 355 | default: |
355 | passed = false; | 356 | passed = false; |
356 | } | 357 | } |
357 | 358 | ||
358 | selftest(passed, "index %i - data error on node %s rc=%i\n", | 359 | selftest(passed, "index %i - data error on node %s rc=%i\n", |
359 | i, args.np->full_name, rc); | 360 | i, args.np->full_name, rc); |
360 | } | 361 | } |
361 | of_node_put(np); | 362 | of_node_put(np); |
362 | } | 363 | } |
363 | 364 | ||
364 | static struct of_device_id match_node_table[] = { | 365 | static struct of_device_id match_node_table[] = { |
365 | { .data = "A", .name = "name0", }, /* Name alone is lowest priority */ | 366 | { .data = "A", .name = "name0", }, /* Name alone is lowest priority */ |
366 | { .data = "B", .type = "type1", }, /* followed by type alone */ | 367 | { .data = "B", .type = "type1", }, /* followed by type alone */ |
367 | 368 | ||
368 | { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */ | 369 | { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */ |
369 | { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */ | 370 | { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */ |
370 | { .data = "Cc", .name = "name2", .type = "type2", }, | 371 | { .data = "Cc", .name = "name2", .type = "type2", }, |
371 | 372 | ||
372 | { .data = "E", .compatible = "compat3" }, | 373 | { .data = "E", .compatible = "compat3" }, |
373 | { .data = "G", .compatible = "compat2", }, | 374 | { .data = "G", .compatible = "compat2", }, |
374 | { .data = "H", .compatible = "compat2", .name = "name5", }, | 375 | { .data = "H", .compatible = "compat2", .name = "name5", }, |
375 | { .data = "I", .compatible = "compat2", .type = "type1", }, | 376 | { .data = "I", .compatible = "compat2", .type = "type1", }, |
376 | { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", }, | 377 | { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", }, |
377 | { .data = "K", .compatible = "compat2", .name = "name9", }, | 378 | { .data = "K", .compatible = "compat2", .name = "name9", }, |
378 | {} | 379 | {} |
379 | }; | 380 | }; |
380 | 381 | ||
381 | static struct { | 382 | static struct { |
382 | const char *path; | 383 | const char *path; |
383 | const char *data; | 384 | const char *data; |
384 | } match_node_tests[] = { | 385 | } match_node_tests[] = { |
385 | { .path = "/testcase-data/match-node/name0", .data = "A", }, | 386 | { .path = "/testcase-data/match-node/name0", .data = "A", }, |
386 | { .path = "/testcase-data/match-node/name1", .data = "B", }, | 387 | { .path = "/testcase-data/match-node/name1", .data = "B", }, |
387 | { .path = "/testcase-data/match-node/a/name2", .data = "Ca", }, | 388 | { .path = "/testcase-data/match-node/a/name2", .data = "Ca", }, |
388 | { .path = "/testcase-data/match-node/b/name2", .data = "Cb", }, | 389 | { .path = "/testcase-data/match-node/b/name2", .data = "Cb", }, |
389 | { .path = "/testcase-data/match-node/c/name2", .data = "Cc", }, | 390 | { .path = "/testcase-data/match-node/c/name2", .data = "Cc", }, |
390 | { .path = "/testcase-data/match-node/name3", .data = "E", }, | 391 | { .path = "/testcase-data/match-node/name3", .data = "E", }, |
391 | { .path = "/testcase-data/match-node/name4", .data = "G", }, | 392 | { .path = "/testcase-data/match-node/name4", .data = "G", }, |
392 | { .path = "/testcase-data/match-node/name5", .data = "H", }, | 393 | { .path = "/testcase-data/match-node/name5", .data = "H", }, |
393 | { .path = "/testcase-data/match-node/name6", .data = "G", }, | 394 | { .path = "/testcase-data/match-node/name6", .data = "G", }, |
394 | { .path = "/testcase-data/match-node/name7", .data = "I", }, | 395 | { .path = "/testcase-data/match-node/name7", .data = "I", }, |
395 | { .path = "/testcase-data/match-node/name8", .data = "J", }, | 396 | { .path = "/testcase-data/match-node/name8", .data = "J", }, |
396 | { .path = "/testcase-data/match-node/name9", .data = "K", }, | 397 | { .path = "/testcase-data/match-node/name9", .data = "K", }, |
397 | }; | 398 | }; |
398 | 399 | ||
399 | static void __init of_selftest_match_node(void) | 400 | static void __init of_selftest_match_node(void) |
400 | { | 401 | { |
401 | struct device_node *np; | 402 | struct device_node *np; |
402 | const struct of_device_id *match; | 403 | const struct of_device_id *match; |
403 | int i; | 404 | int i; |
404 | 405 | ||
405 | for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) { | 406 | for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) { |
406 | np = of_find_node_by_path(match_node_tests[i].path); | 407 | np = of_find_node_by_path(match_node_tests[i].path); |
407 | if (!np) { | 408 | if (!np) { |
408 | selftest(0, "missing testcase node %s\n", | 409 | selftest(0, "missing testcase node %s\n", |
409 | match_node_tests[i].path); | 410 | match_node_tests[i].path); |
410 | continue; | 411 | continue; |
411 | } | 412 | } |
412 | 413 | ||
413 | match = of_match_node(match_node_table, np); | 414 | match = of_match_node(match_node_table, np); |
414 | if (!match) { | 415 | if (!match) { |
415 | selftest(0, "%s didn't match anything\n", | 416 | selftest(0, "%s didn't match anything\n", |
416 | match_node_tests[i].path); | 417 | match_node_tests[i].path); |
417 | continue; | 418 | continue; |
418 | } | 419 | } |
419 | 420 | ||
420 | if (strcmp(match->data, match_node_tests[i].data) != 0) { | 421 | if (strcmp(match->data, match_node_tests[i].data) != 0) { |
421 | selftest(0, "%s got wrong match. expected %s, got %s\n", | 422 | selftest(0, "%s got wrong match. expected %s, got %s\n", |
422 | match_node_tests[i].path, match_node_tests[i].data, | 423 | match_node_tests[i].path, match_node_tests[i].data, |
423 | (const char *)match->data); | 424 | (const char *)match->data); |
424 | continue; | 425 | continue; |
425 | } | 426 | } |
426 | selftest(1, "passed"); | 427 | selftest(1, "passed"); |
427 | } | 428 | } |
428 | } | 429 | } |
429 | 430 | ||
431 | static void __init of_selftest_platform_populate(void) | ||
432 | { | ||
433 | int irq; | ||
434 | struct device_node *np; | ||
435 | struct platform_device *pdev; | ||
436 | |||
437 | np = of_find_node_by_path("/testcase-data"); | ||
438 | of_platform_populate(np, of_default_bus_match_table, NULL, NULL); | ||
439 | |||
440 | /* Test that a missing irq domain returns -EPROBE_DEFER */ | ||
441 | np = of_find_node_by_path("/testcase-data/testcase-device1"); | ||
442 | pdev = of_find_device_by_node(np); | ||
443 | if (!pdev) | ||
444 | selftest(0, "device 1 creation failed\n"); | ||
445 | irq = platform_get_irq(pdev, 0); | ||
446 | if (irq != -EPROBE_DEFER) | ||
447 | selftest(0, "device deferred probe failed - %d\n", irq); | ||
448 | |||
449 | /* Test that a parsing failure does not return -EPROBE_DEFER */ | ||
450 | np = of_find_node_by_path("/testcase-data/testcase-device2"); | ||
451 | pdev = of_find_device_by_node(np); | ||
452 | if (!pdev) | ||
453 | selftest(0, "device 2 creation failed\n"); | ||
454 | irq = platform_get_irq(pdev, 0); | ||
455 | if (irq >= 0 || irq == -EPROBE_DEFER) | ||
456 | selftest(0, "device parsing error failed - %d\n", irq); | ||
457 | |||
458 | selftest(1, "passed"); | ||
459 | } | ||
460 | |||
430 | static int __init of_selftest(void) | 461 | static int __init of_selftest(void) |
431 | { | 462 | { |
432 | struct device_node *np; | 463 | struct device_node *np; |
433 | 464 | ||
434 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | 465 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); |
435 | if (!np) { | 466 | if (!np) { |
436 | pr_info("No testcase data in device tree; not running tests\n"); | 467 | pr_info("No testcase data in device tree; not running tests\n"); |
437 | return 0; | 468 | return 0; |
438 | } | 469 | } |
439 | of_node_put(np); | 470 | of_node_put(np); |
440 | 471 | ||
441 | pr_info("start of selftest - you will see error messages\n"); | 472 | pr_info("start of selftest - you will see error messages\n"); |
442 | of_selftest_dynamic(); | 473 | of_selftest_dynamic(); |
443 | of_selftest_parse_phandle_with_args(); | 474 | of_selftest_parse_phandle_with_args(); |
444 | of_selftest_property_match_string(); | 475 | of_selftest_property_match_string(); |
445 | of_selftest_parse_interrupts(); | 476 | of_selftest_parse_interrupts(); |
446 | of_selftest_parse_interrupts_extended(); | 477 | of_selftest_parse_interrupts_extended(); |
447 | of_selftest_match_node(); | 478 | of_selftest_match_node(); |
479 | of_selftest_platform_populate(); | ||
448 | pr_info("end of selftest - %i passed, %i failed\n", | 480 | pr_info("end of selftest - %i passed, %i failed\n", |
449 | selftest_results.passed, selftest_results.failed); | 481 | selftest_results.passed, selftest_results.failed); |
450 | return 0; | 482 | return 0; |
451 | } | 483 | } |
452 | late_initcall(of_selftest); | 484 | late_initcall(of_selftest); |
453 | 485 |
drivers/of/testcase-data/tests-interrupts.dtsi
1 | 1 | ||
2 | / { | 2 | / { |
3 | testcase-data { | 3 | testcase-data { |
4 | interrupts { | 4 | interrupts { |
5 | #address-cells = <1>; | 5 | #address-cells = <1>; |
6 | #size-cells = <1>; | 6 | #size-cells = <1>; |
7 | test_intc0: intc0 { | 7 | test_intc0: intc0 { |
8 | interrupt-controller; | 8 | interrupt-controller; |
9 | #interrupt-cells = <1>; | 9 | #interrupt-cells = <1>; |
10 | }; | 10 | }; |
11 | 11 | ||
12 | test_intc1: intc1 { | 12 | test_intc1: intc1 { |
13 | interrupt-controller; | 13 | interrupt-controller; |
14 | #interrupt-cells = <3>; | 14 | #interrupt-cells = <3>; |
15 | }; | 15 | }; |
16 | 16 | ||
17 | test_intc2: intc2 { | 17 | test_intc2: intc2 { |
18 | interrupt-controller; | 18 | interrupt-controller; |
19 | #interrupt-cells = <2>; | 19 | #interrupt-cells = <2>; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | test_intmap0: intmap0 { | 22 | test_intmap0: intmap0 { |
23 | #interrupt-cells = <1>; | 23 | #interrupt-cells = <1>; |
24 | #address-cells = <0>; | 24 | #address-cells = <0>; |
25 | interrupt-map = <1 &test_intc0 9>, | 25 | interrupt-map = <1 &test_intc0 9>, |
26 | <2 &test_intc1 10 11 12>, | 26 | <2 &test_intc1 10 11 12>, |
27 | <3 &test_intc2 13 14>, | 27 | <3 &test_intc2 13 14>, |
28 | <4 &test_intc2 15 16>; | 28 | <4 &test_intc2 15 16>; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | test_intmap1: intmap1 { | 31 | test_intmap1: intmap1 { |
32 | #interrupt-cells = <2>; | 32 | #interrupt-cells = <2>; |
33 | interrupt-map = <0x5000 1 2 &test_intc0 15>; | 33 | interrupt-map = <0x5000 1 2 &test_intc0 15>; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | interrupts0 { | 36 | interrupts0 { |
37 | interrupt-parent = <&test_intc0>; | 37 | interrupt-parent = <&test_intc0>; |
38 | interrupts = <1>, <2>, <3>, <4>; | 38 | interrupts = <1>, <2>, <3>, <4>; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | interrupts1 { | 41 | interrupts1 { |
42 | interrupt-parent = <&test_intmap0>; | 42 | interrupt-parent = <&test_intmap0>; |
43 | interrupts = <1>, <2>, <3>, <4>; | 43 | interrupts = <1>, <2>, <3>, <4>; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | interrupts-extended0 { | 46 | interrupts-extended0 { |
47 | reg = <0x5000 0x100>; | 47 | reg = <0x5000 0x100>; |
48 | interrupts-extended = <&test_intc0 1>, | 48 | interrupts-extended = <&test_intc0 1>, |
49 | <&test_intc1 2 3 4>, | 49 | <&test_intc1 2 3 4>, |
50 | <&test_intc2 5 6>, | 50 | <&test_intc2 5 6>, |
51 | <&test_intmap0 1>, | 51 | <&test_intmap0 1>, |
52 | <&test_intmap0 2>, | 52 | <&test_intmap0 2>, |
53 | <&test_intmap0 3>, | 53 | <&test_intmap0 3>, |
54 | <&test_intmap1 1 2>; | 54 | <&test_intmap1 1 2>; |
55 | }; | 55 | }; |
56 | }; | 56 | }; |
57 | |||
58 | testcase-device1 { | ||
59 | compatible = "testcase-device"; | ||
60 | interrupt-parent = <&test_intc0>; | ||
61 | interrupts = <1>; | ||
62 | }; | ||
63 | |||
64 | testcase-device2 { | ||
65 | compatible = "testcase-device"; | ||
66 | interrupt-parent = <&test_intc2>; | ||
67 | interrupts = <1>; /* invalid specifier - too short */ | ||
68 | }; | ||
57 | }; | 69 | }; |
70 | |||
58 | }; | 71 | }; |
59 | 72 |
include/linux/of_irq.h
1 | #ifndef __OF_IRQ_H | 1 | #ifndef __OF_IRQ_H |
2 | #define __OF_IRQ_H | 2 | #define __OF_IRQ_H |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/errno.h> | 5 | #include <linux/errno.h> |
6 | #include <linux/irq.h> | 6 | #include <linux/irq.h> |
7 | #include <linux/irqdomain.h> | 7 | #include <linux/irqdomain.h> |
8 | #include <linux/ioport.h> | 8 | #include <linux/ioport.h> |
9 | #include <linux/of.h> | 9 | #include <linux/of.h> |
10 | 10 | ||
11 | typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *); | 11 | typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *); |
12 | 12 | ||
13 | /* | 13 | /* |
14 | * Workarounds only applied to 32bit powermac machines | 14 | * Workarounds only applied to 32bit powermac machines |
15 | */ | 15 | */ |
16 | #define OF_IMAP_OLDWORLD_MAC 0x00000001 | 16 | #define OF_IMAP_OLDWORLD_MAC 0x00000001 |
17 | #define OF_IMAP_NO_PHANDLE 0x00000002 | 17 | #define OF_IMAP_NO_PHANDLE 0x00000002 |
18 | 18 | ||
19 | #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) | 19 | #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) |
20 | extern unsigned int of_irq_workarounds; | 20 | extern unsigned int of_irq_workarounds; |
21 | extern struct device_node *of_irq_dflt_pic; | 21 | extern struct device_node *of_irq_dflt_pic; |
22 | extern int of_irq_parse_oldworld(struct device_node *device, int index, | 22 | extern int of_irq_parse_oldworld(struct device_node *device, int index, |
23 | struct of_phandle_args *out_irq); | 23 | struct of_phandle_args *out_irq); |
24 | #else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ | 24 | #else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ |
25 | #define of_irq_workarounds (0) | 25 | #define of_irq_workarounds (0) |
26 | #define of_irq_dflt_pic (NULL) | 26 | #define of_irq_dflt_pic (NULL) |
27 | static inline int of_irq_parse_oldworld(struct device_node *device, int index, | 27 | static inline int of_irq_parse_oldworld(struct device_node *device, int index, |
28 | struct of_phandle_args *out_irq) | 28 | struct of_phandle_args *out_irq) |
29 | { | 29 | { |
30 | return -EINVAL; | 30 | return -EINVAL; |
31 | } | 31 | } |
32 | #endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ | 32 | #endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ |
33 | 33 | ||
34 | extern int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq); | 34 | extern int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq); |
35 | extern int of_irq_parse_one(struct device_node *device, int index, | 35 | extern int of_irq_parse_one(struct device_node *device, int index, |
36 | struct of_phandle_args *out_irq); | 36 | struct of_phandle_args *out_irq); |
37 | extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data); | 37 | extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data); |
38 | extern int of_irq_to_resource(struct device_node *dev, int index, | 38 | extern int of_irq_to_resource(struct device_node *dev, int index, |
39 | struct resource *r); | 39 | struct resource *r); |
40 | extern int of_irq_to_resource_table(struct device_node *dev, | 40 | extern int of_irq_to_resource_table(struct device_node *dev, |
41 | struct resource *res, int nr_irqs); | 41 | struct resource *res, int nr_irqs); |
42 | 42 | ||
43 | extern void of_irq_init(const struct of_device_id *matches); | 43 | extern void of_irq_init(const struct of_device_id *matches); |
44 | 44 | ||
45 | #ifdef CONFIG_OF_IRQ | 45 | #ifdef CONFIG_OF_IRQ |
46 | extern int of_irq_count(struct device_node *dev); | 46 | extern int of_irq_count(struct device_node *dev); |
47 | extern int of_irq_get(struct device_node *dev, int index); | ||
47 | #else | 48 | #else |
48 | static inline int of_irq_count(struct device_node *dev) | 49 | static inline int of_irq_count(struct device_node *dev) |
50 | { | ||
51 | return 0; | ||
52 | } | ||
53 | static inline int of_irq_get(struct device_node *dev, int index) | ||
49 | { | 54 | { |
50 | return 0; | 55 | return 0; |
51 | } | 56 | } |
52 | #endif | 57 | #endif |
53 | 58 | ||
54 | #if defined(CONFIG_OF) | 59 | #if defined(CONFIG_OF) |
55 | /* | 60 | /* |
56 | * irq_of_parse_and_map() is used by all OF enabled platforms; but SPARC | 61 | * irq_of_parse_and_map() is used by all OF enabled platforms; but SPARC |
57 | * implements it differently. However, the prototype is the same for all, | 62 | * implements it differently. However, the prototype is the same for all, |
58 | * so declare it here regardless of the CONFIG_OF_IRQ setting. | 63 | * so declare it here regardless of the CONFIG_OF_IRQ setting. |
59 | */ | 64 | */ |
60 | extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); | 65 | extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); |
61 | extern struct device_node *of_irq_find_parent(struct device_node *child); | 66 | extern struct device_node *of_irq_find_parent(struct device_node *child); |
62 | 67 | ||
63 | #else /* !CONFIG_OF */ | 68 | #else /* !CONFIG_OF */ |
64 | static inline unsigned int irq_of_parse_and_map(struct device_node *dev, | 69 | static inline unsigned int irq_of_parse_and_map(struct device_node *dev, |
65 | int index) | 70 | int index) |
66 | { | 71 | { |
67 | return 0; | 72 | return 0; |
68 | } | 73 | } |
69 | 74 | ||
70 | static inline void *of_irq_find_parent(struct device_node *child) | 75 | static inline void *of_irq_find_parent(struct device_node *child) |
71 | { | 76 | { |
72 | return NULL; | 77 | return NULL; |
73 | } | 78 | } |
74 | #endif /* !CONFIG_OF */ | 79 | #endif /* !CONFIG_OF */ |
75 | 80 | ||
76 | #endif /* __OF_IRQ_H */ | 81 | #endif /* __OF_IRQ_H */ |
77 | 82 |