Commit 160e1fd10a287bb805745ea4e5b8bb383b686b7f

Authored by Giuseppe CAVALLARO
Committed by David S. Miller
1 parent 8c2a7a5d2c

stmmac: make the STi Layer compatible to STiH407

This adds the missing compatibility to the STiH407 SoC.

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 3 additions and 2 deletions Inline Diff

Documentation/devicetree/bindings/net/sti-dwmac.txt
1 STMicroelectronics SoC DWMAC glue layer controller 1 STMicroelectronics SoC DWMAC glue layer controller
2 2
3 The device node has following properties. 3 The device node has following properties.
4 4
5 Required properties: 5 Required properties:
6 - compatible : Can be "st,stih415-dwmac", "st,stih416-dwmac" or 6 - compatible : Can be "st,stih415-dwmac", "st,stih416-dwmac",
7 "st,stid127-dwmac". 7 "st,stid127-dwmac", "st,stih407-dwmac".
8 - reg : Offset of the glue configuration register map in system 8 - reg : Offset of the glue configuration register map in system
9 configuration regmap pointed by st,syscon property and size. 9 configuration regmap pointed by st,syscon property and size.
10 10
11 - reg-names : Should be "sti-ethconf". 11 - reg-names : Should be "sti-ethconf".
12 12
13 - st,syscon : Should be phandle to system configuration node which 13 - st,syscon : Should be phandle to system configuration node which
14 encompases this glue registers. 14 encompases this glue registers.
15 15
16 - st,tx-retime-src: On STi Parts for Giga bit speeds, 125Mhz clocks can be 16 - st,tx-retime-src: On STi Parts for Giga bit speeds, 125Mhz clocks can be
17 wired up in from different sources. One via TXCLK pin and other via CLK_125 17 wired up in from different sources. One via TXCLK pin and other via CLK_125
18 pin. This wiring is totally board dependent. However the retiming glue 18 pin. This wiring is totally board dependent. However the retiming glue
19 logic should be configured accordingly. Possible values for this property 19 logic should be configured accordingly. Possible values for this property
20 20
21 "txclk" - if 125Mhz clock is wired up via txclk line. 21 "txclk" - if 125Mhz clock is wired up via txclk line.
22 "clk_125" - if 125Mhz clock is wired up via clk_125 line. 22 "clk_125" - if 125Mhz clock is wired up via clk_125 line.
23 23
24 This property is only valid for Giga bit setup( GMII, RGMII), and it is 24 This property is only valid for Giga bit setup( GMII, RGMII), and it is
25 un-used for non-giga bit (MII and RMII) setups. Also note that internal 25 un-used for non-giga bit (MII and RMII) setups. Also note that internal
26 clockgen can not generate stable 125Mhz clock. 26 clockgen can not generate stable 125Mhz clock.
27 27
28 - st,ext-phyclk: This boolean property indicates who is generating the clock 28 - st,ext-phyclk: This boolean property indicates who is generating the clock
29 for tx and rx. This property is only valid for RMII case where the clock can 29 for tx and rx. This property is only valid for RMII case where the clock can
30 be generated from the MAC or PHY. 30 be generated from the MAC or PHY.
31 31
32 - clock-names: should be "sti-ethclk". 32 - clock-names: should be "sti-ethclk".
33 - clocks: Should point to ethernet clockgen which can generate phyclk. 33 - clocks: Should point to ethernet clockgen which can generate phyclk.
34 34
35 35
36 Example: 36 Example:
37 37
38 ethernet0: dwmac@fe810000 { 38 ethernet0: dwmac@fe810000 {
39 device_type = "network"; 39 device_type = "network";
40 compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710"; 40 compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
41 reg = <0xfe810000 0x8000>, <0x8bc 0x4>; 41 reg = <0xfe810000 0x8000>, <0x8bc 0x4>;
42 reg-names = "stmmaceth", "sti-ethconf"; 42 reg-names = "stmmaceth", "sti-ethconf";
43 interrupts = <0 133 0>, <0 134 0>, <0 135 0>; 43 interrupts = <0 133 0>, <0 134 0>, <0 135 0>;
44 interrupt-names = "macirq", "eth_wake_irq", "eth_lpi"; 44 interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
45 phy-mode = "mii"; 45 phy-mode = "mii";
46 46
47 st,syscon = <&syscfg_rear>; 47 st,syscon = <&syscfg_rear>;
48 48
49 snps,pbl = <32>; 49 snps,pbl = <32>;
50 snps,mixed-burst; 50 snps,mixed-burst;
51 51
52 resets = <&softreset STIH416_ETH0_SOFTRESET>; 52 resets = <&softreset STIH416_ETH0_SOFTRESET>;
53 reset-names = "stmmaceth"; 53 reset-names = "stmmaceth";
54 pinctrl-0 = <&pinctrl_mii0>; 54 pinctrl-0 = <&pinctrl_mii0>;
55 pinctrl-names = "default"; 55 pinctrl-names = "default";
56 clocks = <&CLK_S_GMAC0_PHY>; 56 clocks = <&CLK_S_GMAC0_PHY>;
57 clock-names = "stmmaceth"; 57 clock-names = "stmmaceth";
58 }; 58 };
59 59
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
1 /******************************************************************************* 1 /*******************************************************************************
2 This contains the functions to handle the platform driver. 2 This contains the functions to handle the platform driver.
3 3
4 Copyright (C) 2007-2011 STMicroelectronics Ltd 4 Copyright (C) 2007-2011 STMicroelectronics Ltd
5 5
6 This program is free software; you can redistribute it and/or modify it 6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License, 7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation. 8 version 2, as published by the Free Software Foundation.
9 9
10 This program is distributed in the hope it will be useful, but WITHOUT 10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details. 13 more details.
14 14
15 You should have received a copy of the GNU General Public License along with 15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc., 16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 18
19 The full GNU General Public License is included in this distribution in 19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING". 20 the file called "COPYING".
21 21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23 *******************************************************************************/ 23 *******************************************************************************/
24 24
25 #include <linux/platform_device.h> 25 #include <linux/platform_device.h>
26 #include <linux/io.h> 26 #include <linux/io.h>
27 #include <linux/of.h> 27 #include <linux/of.h>
28 #include <linux/of_net.h> 28 #include <linux/of_net.h>
29 #include <linux/of_device.h> 29 #include <linux/of_device.h>
30 #include "stmmac.h" 30 #include "stmmac.h"
31 31
32 static const struct of_device_id stmmac_dt_ids[] = { 32 static const struct of_device_id stmmac_dt_ids[] = {
33 #ifdef CONFIG_DWMAC_MESON 33 #ifdef CONFIG_DWMAC_MESON
34 { .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data}, 34 { .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data},
35 #endif 35 #endif
36 #ifdef CONFIG_DWMAC_SUNXI 36 #ifdef CONFIG_DWMAC_SUNXI
37 { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data}, 37 { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
38 #endif 38 #endif
39 #ifdef CONFIG_DWMAC_STI 39 #ifdef CONFIG_DWMAC_STI
40 { .compatible = "st,stih415-dwmac", .data = &sti_gmac_data}, 40 { .compatible = "st,stih415-dwmac", .data = &sti_gmac_data},
41 { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data}, 41 { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data},
42 { .compatible = "st,stid127-dwmac", .data = &sti_gmac_data}, 42 { .compatible = "st,stid127-dwmac", .data = &sti_gmac_data},
43 { .compatible = "st,stih407-dwmac", .data = &sti_gmac_data},
43 #endif 44 #endif
44 #ifdef CONFIG_DWMAC_SOCFPGA 45 #ifdef CONFIG_DWMAC_SOCFPGA
45 { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data }, 46 { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
46 #endif 47 #endif
47 /* SoC specific glue layers should come before generic bindings */ 48 /* SoC specific glue layers should come before generic bindings */
48 { .compatible = "st,spear600-gmac"}, 49 { .compatible = "st,spear600-gmac"},
49 { .compatible = "snps,dwmac-3.610"}, 50 { .compatible = "snps,dwmac-3.610"},
50 { .compatible = "snps,dwmac-3.70a"}, 51 { .compatible = "snps,dwmac-3.70a"},
51 { .compatible = "snps,dwmac-3.710"}, 52 { .compatible = "snps,dwmac-3.710"},
52 { .compatible = "snps,dwmac"}, 53 { .compatible = "snps,dwmac"},
53 { /* sentinel */ } 54 { /* sentinel */ }
54 }; 55 };
55 MODULE_DEVICE_TABLE(of, stmmac_dt_ids); 56 MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
56 57
57 #ifdef CONFIG_OF 58 #ifdef CONFIG_OF
58 59
59 /* This function validates the number of Multicast filtering bins specified 60 /* This function validates the number of Multicast filtering bins specified
60 * by the configuration through the device tree. The Synopsys GMAC supports 61 * by the configuration through the device tree. The Synopsys GMAC supports
61 * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC 62 * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC
62 * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds 63 * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds
63 * to 7 bits, and 256 refers to 8 bits of the CRC. Any other setting is 64 * to 7 bits, and 256 refers to 8 bits of the CRC. Any other setting is
64 * invalid and will cause the filtering algorithm to use Multicast 65 * invalid and will cause the filtering algorithm to use Multicast
65 * promiscuous mode. 66 * promiscuous mode.
66 */ 67 */
67 static int dwmac1000_validate_mcast_bins(int mcast_bins) 68 static int dwmac1000_validate_mcast_bins(int mcast_bins)
68 { 69 {
69 int x = mcast_bins; 70 int x = mcast_bins;
70 71
71 switch (x) { 72 switch (x) {
72 case HASH_TABLE_SIZE: 73 case HASH_TABLE_SIZE:
73 case 128: 74 case 128:
74 case 256: 75 case 256:
75 break; 76 break;
76 default: 77 default:
77 x = 0; 78 x = 0;
78 pr_info("Hash table entries set to unexpected value %d", 79 pr_info("Hash table entries set to unexpected value %d",
79 mcast_bins); 80 mcast_bins);
80 break; 81 break;
81 } 82 }
82 return x; 83 return x;
83 } 84 }
84 85
85 /* This function validates the number of Unicast address entries supported 86 /* This function validates the number of Unicast address entries supported
86 * by a particular Synopsys 10/100/1000 controller. The Synopsys controller 87 * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
87 * supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter 88 * supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter
88 * logic. This function validates a valid, supported configuration is 89 * logic. This function validates a valid, supported configuration is
89 * selected, and defaults to 1 Unicast address if an unsupported 90 * selected, and defaults to 1 Unicast address if an unsupported
90 * configuration is selected. 91 * configuration is selected.
91 */ 92 */
92 static int dwmac1000_validate_ucast_entries(int ucast_entries) 93 static int dwmac1000_validate_ucast_entries(int ucast_entries)
93 { 94 {
94 int x = ucast_entries; 95 int x = ucast_entries;
95 96
96 switch (x) { 97 switch (x) {
97 case 1: 98 case 1:
98 case 32: 99 case 32:
99 case 64: 100 case 64:
100 case 128: 101 case 128:
101 break; 102 break;
102 default: 103 default:
103 x = 1; 104 x = 1;
104 pr_info("Unicast table entries set to unexpected value %d\n", 105 pr_info("Unicast table entries set to unexpected value %d\n",
105 ucast_entries); 106 ucast_entries);
106 break; 107 break;
107 } 108 }
108 return x; 109 return x;
109 } 110 }
110 111
111 static int stmmac_probe_config_dt(struct platform_device *pdev, 112 static int stmmac_probe_config_dt(struct platform_device *pdev,
112 struct plat_stmmacenet_data *plat, 113 struct plat_stmmacenet_data *plat,
113 const char **mac) 114 const char **mac)
114 { 115 {
115 struct device_node *np = pdev->dev.of_node; 116 struct device_node *np = pdev->dev.of_node;
116 struct stmmac_dma_cfg *dma_cfg; 117 struct stmmac_dma_cfg *dma_cfg;
117 const struct of_device_id *device; 118 const struct of_device_id *device;
118 119
119 if (!np) 120 if (!np)
120 return -ENODEV; 121 return -ENODEV;
121 122
122 device = of_match_device(stmmac_dt_ids, &pdev->dev); 123 device = of_match_device(stmmac_dt_ids, &pdev->dev);
123 if (!device) 124 if (!device)
124 return -ENODEV; 125 return -ENODEV;
125 126
126 if (device->data) { 127 if (device->data) {
127 const struct stmmac_of_data *data = device->data; 128 const struct stmmac_of_data *data = device->data;
128 plat->has_gmac = data->has_gmac; 129 plat->has_gmac = data->has_gmac;
129 plat->enh_desc = data->enh_desc; 130 plat->enh_desc = data->enh_desc;
130 plat->tx_coe = data->tx_coe; 131 plat->tx_coe = data->tx_coe;
131 plat->rx_coe = data->rx_coe; 132 plat->rx_coe = data->rx_coe;
132 plat->bugged_jumbo = data->bugged_jumbo; 133 plat->bugged_jumbo = data->bugged_jumbo;
133 plat->pmt = data->pmt; 134 plat->pmt = data->pmt;
134 plat->riwt_off = data->riwt_off; 135 plat->riwt_off = data->riwt_off;
135 plat->fix_mac_speed = data->fix_mac_speed; 136 plat->fix_mac_speed = data->fix_mac_speed;
136 plat->bus_setup = data->bus_setup; 137 plat->bus_setup = data->bus_setup;
137 plat->setup = data->setup; 138 plat->setup = data->setup;
138 plat->free = data->free; 139 plat->free = data->free;
139 plat->init = data->init; 140 plat->init = data->init;
140 plat->exit = data->exit; 141 plat->exit = data->exit;
141 } 142 }
142 143
143 *mac = of_get_mac_address(np); 144 *mac = of_get_mac_address(np);
144 plat->interface = of_get_phy_mode(np); 145 plat->interface = of_get_phy_mode(np);
145 146
146 /* Get max speed of operation from device tree */ 147 /* Get max speed of operation from device tree */
147 if (of_property_read_u32(np, "max-speed", &plat->max_speed)) 148 if (of_property_read_u32(np, "max-speed", &plat->max_speed))
148 plat->max_speed = -1; 149 plat->max_speed = -1;
149 150
150 plat->bus_id = of_alias_get_id(np, "ethernet"); 151 plat->bus_id = of_alias_get_id(np, "ethernet");
151 if (plat->bus_id < 0) 152 if (plat->bus_id < 0)
152 plat->bus_id = 0; 153 plat->bus_id = 0;
153 154
154 /* Default to phy auto-detection */ 155 /* Default to phy auto-detection */
155 plat->phy_addr = -1; 156 plat->phy_addr = -1;
156 157
157 /* "snps,phy-addr" is not a standard property. Mark it as deprecated 158 /* "snps,phy-addr" is not a standard property. Mark it as deprecated
158 * and warn of its use. Remove this when phy node support is added. 159 * and warn of its use. Remove this when phy node support is added.
159 */ 160 */
160 if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) 161 if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
161 dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); 162 dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
162 163
163 if (plat->phy_bus_name) 164 if (plat->phy_bus_name)
164 plat->mdio_bus_data = NULL; 165 plat->mdio_bus_data = NULL;
165 else 166 else
166 plat->mdio_bus_data = 167 plat->mdio_bus_data =
167 devm_kzalloc(&pdev->dev, 168 devm_kzalloc(&pdev->dev,
168 sizeof(struct stmmac_mdio_bus_data), 169 sizeof(struct stmmac_mdio_bus_data),
169 GFP_KERNEL); 170 GFP_KERNEL);
170 171
171 plat->force_sf_dma_mode = 172 plat->force_sf_dma_mode =
172 of_property_read_bool(np, "snps,force_sf_dma_mode"); 173 of_property_read_bool(np, "snps,force_sf_dma_mode");
173 174
174 /* Set the maxmtu to a default of JUMBO_LEN in case the 175 /* Set the maxmtu to a default of JUMBO_LEN in case the
175 * parameter is not present in the device tree. 176 * parameter is not present in the device tree.
176 */ 177 */
177 plat->maxmtu = JUMBO_LEN; 178 plat->maxmtu = JUMBO_LEN;
178 179
179 /* Set default value for multicast hash bins */ 180 /* Set default value for multicast hash bins */
180 plat->multicast_filter_bins = HASH_TABLE_SIZE; 181 plat->multicast_filter_bins = HASH_TABLE_SIZE;
181 182
182 /* Set default value for unicast filter entries */ 183 /* Set default value for unicast filter entries */
183 plat->unicast_filter_entries = 1; 184 plat->unicast_filter_entries = 1;
184 185
185 /* 186 /*
186 * Currently only the properties needed on SPEAr600 187 * Currently only the properties needed on SPEAr600
187 * are provided. All other properties should be added 188 * are provided. All other properties should be added
188 * once needed on other platforms. 189 * once needed on other platforms.
189 */ 190 */
190 if (of_device_is_compatible(np, "st,spear600-gmac") || 191 if (of_device_is_compatible(np, "st,spear600-gmac") ||
191 of_device_is_compatible(np, "snps,dwmac-3.70a") || 192 of_device_is_compatible(np, "snps,dwmac-3.70a") ||
192 of_device_is_compatible(np, "snps,dwmac")) { 193 of_device_is_compatible(np, "snps,dwmac")) {
193 /* Note that the max-frame-size parameter as defined in the 194 /* Note that the max-frame-size parameter as defined in the
194 * ePAPR v1.1 spec is defined as max-frame-size, it's 195 * ePAPR v1.1 spec is defined as max-frame-size, it's
195 * actually used as the IEEE definition of MAC Client 196 * actually used as the IEEE definition of MAC Client
196 * data, or MTU. The ePAPR specification is confusing as 197 * data, or MTU. The ePAPR specification is confusing as
197 * the definition is max-frame-size, but usage examples 198 * the definition is max-frame-size, but usage examples
198 * are clearly MTUs 199 * are clearly MTUs
199 */ 200 */
200 of_property_read_u32(np, "max-frame-size", &plat->maxmtu); 201 of_property_read_u32(np, "max-frame-size", &plat->maxmtu);
201 of_property_read_u32(np, "snps,multicast-filter-bins", 202 of_property_read_u32(np, "snps,multicast-filter-bins",
202 &plat->multicast_filter_bins); 203 &plat->multicast_filter_bins);
203 of_property_read_u32(np, "snps,perfect-filter-entries", 204 of_property_read_u32(np, "snps,perfect-filter-entries",
204 &plat->unicast_filter_entries); 205 &plat->unicast_filter_entries);
205 plat->unicast_filter_entries = dwmac1000_validate_ucast_entries( 206 plat->unicast_filter_entries = dwmac1000_validate_ucast_entries(
206 plat->unicast_filter_entries); 207 plat->unicast_filter_entries);
207 plat->multicast_filter_bins = dwmac1000_validate_mcast_bins( 208 plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
208 plat->multicast_filter_bins); 209 plat->multicast_filter_bins);
209 plat->has_gmac = 1; 210 plat->has_gmac = 1;
210 plat->pmt = 1; 211 plat->pmt = 1;
211 } 212 }
212 213
213 if (of_device_is_compatible(np, "snps,dwmac-3.610") || 214 if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
214 of_device_is_compatible(np, "snps,dwmac-3.710")) { 215 of_device_is_compatible(np, "snps,dwmac-3.710")) {
215 plat->enh_desc = 1; 216 plat->enh_desc = 1;
216 plat->bugged_jumbo = 1; 217 plat->bugged_jumbo = 1;
217 plat->force_sf_dma_mode = 1; 218 plat->force_sf_dma_mode = 1;
218 } 219 }
219 220
220 if (of_find_property(np, "snps,pbl", NULL)) { 221 if (of_find_property(np, "snps,pbl", NULL)) {
221 dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), 222 dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
222 GFP_KERNEL); 223 GFP_KERNEL);
223 if (!dma_cfg) 224 if (!dma_cfg)
224 return -ENOMEM; 225 return -ENOMEM;
225 plat->dma_cfg = dma_cfg; 226 plat->dma_cfg = dma_cfg;
226 of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); 227 of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
227 dma_cfg->fixed_burst = 228 dma_cfg->fixed_burst =
228 of_property_read_bool(np, "snps,fixed-burst"); 229 of_property_read_bool(np, "snps,fixed-burst");
229 dma_cfg->mixed_burst = 230 dma_cfg->mixed_burst =
230 of_property_read_bool(np, "snps,mixed-burst"); 231 of_property_read_bool(np, "snps,mixed-burst");
231 } 232 }
232 plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode"); 233 plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
233 if (plat->force_thresh_dma_mode) { 234 if (plat->force_thresh_dma_mode) {
234 plat->force_sf_dma_mode = 0; 235 plat->force_sf_dma_mode = 0;
235 pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set."); 236 pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
236 } 237 }
237 238
238 return 0; 239 return 0;
239 } 240 }
240 #else 241 #else
241 static int stmmac_probe_config_dt(struct platform_device *pdev, 242 static int stmmac_probe_config_dt(struct platform_device *pdev,
242 struct plat_stmmacenet_data *plat, 243 struct plat_stmmacenet_data *plat,
243 const char **mac) 244 const char **mac)
244 { 245 {
245 return -ENOSYS; 246 return -ENOSYS;
246 } 247 }
247 #endif /* CONFIG_OF */ 248 #endif /* CONFIG_OF */
248 249
249 /** 250 /**
250 * stmmac_pltfr_probe 251 * stmmac_pltfr_probe
251 * @pdev: platform device pointer 252 * @pdev: platform device pointer
252 * Description: platform_device probe function. It allocates 253 * Description: platform_device probe function. It allocates
253 * the necessary resources and invokes the main to init 254 * the necessary resources and invokes the main to init
254 * the net device, register the mdio bus etc. 255 * the net device, register the mdio bus etc.
255 */ 256 */
256 static int stmmac_pltfr_probe(struct platform_device *pdev) 257 static int stmmac_pltfr_probe(struct platform_device *pdev)
257 { 258 {
258 int ret = 0; 259 int ret = 0;
259 struct resource *res; 260 struct resource *res;
260 struct device *dev = &pdev->dev; 261 struct device *dev = &pdev->dev;
261 void __iomem *addr = NULL; 262 void __iomem *addr = NULL;
262 struct stmmac_priv *priv = NULL; 263 struct stmmac_priv *priv = NULL;
263 struct plat_stmmacenet_data *plat_dat = NULL; 264 struct plat_stmmacenet_data *plat_dat = NULL;
264 const char *mac = NULL; 265 const char *mac = NULL;
265 266
266 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 267 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
267 addr = devm_ioremap_resource(dev, res); 268 addr = devm_ioremap_resource(dev, res);
268 if (IS_ERR(addr)) 269 if (IS_ERR(addr))
269 return PTR_ERR(addr); 270 return PTR_ERR(addr);
270 271
271 plat_dat = dev_get_platdata(&pdev->dev); 272 plat_dat = dev_get_platdata(&pdev->dev);
272 if (pdev->dev.of_node) { 273 if (pdev->dev.of_node) {
273 if (!plat_dat) 274 if (!plat_dat)
274 plat_dat = devm_kzalloc(&pdev->dev, 275 plat_dat = devm_kzalloc(&pdev->dev,
275 sizeof(struct plat_stmmacenet_data), 276 sizeof(struct plat_stmmacenet_data),
276 GFP_KERNEL); 277 GFP_KERNEL);
277 if (!plat_dat) { 278 if (!plat_dat) {
278 pr_err("%s: ERROR: no memory", __func__); 279 pr_err("%s: ERROR: no memory", __func__);
279 return -ENOMEM; 280 return -ENOMEM;
280 } 281 }
281 282
282 ret = stmmac_probe_config_dt(pdev, plat_dat, &mac); 283 ret = stmmac_probe_config_dt(pdev, plat_dat, &mac);
283 if (ret) { 284 if (ret) {
284 pr_err("%s: main dt probe failed", __func__); 285 pr_err("%s: main dt probe failed", __func__);
285 return ret; 286 return ret;
286 } 287 }
287 } 288 }
288 289
289 /* Custom setup (if needed) */ 290 /* Custom setup (if needed) */
290 if (plat_dat->setup) { 291 if (plat_dat->setup) {
291 plat_dat->bsp_priv = plat_dat->setup(pdev); 292 plat_dat->bsp_priv = plat_dat->setup(pdev);
292 if (IS_ERR(plat_dat->bsp_priv)) 293 if (IS_ERR(plat_dat->bsp_priv))
293 return PTR_ERR(plat_dat->bsp_priv); 294 return PTR_ERR(plat_dat->bsp_priv);
294 } 295 }
295 296
296 /* Custom initialisation (if needed)*/ 297 /* Custom initialisation (if needed)*/
297 if (plat_dat->init) { 298 if (plat_dat->init) {
298 ret = plat_dat->init(pdev, plat_dat->bsp_priv); 299 ret = plat_dat->init(pdev, plat_dat->bsp_priv);
299 if (unlikely(ret)) 300 if (unlikely(ret))
300 return ret; 301 return ret;
301 } 302 }
302 303
303 priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr); 304 priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr);
304 if (IS_ERR(priv)) { 305 if (IS_ERR(priv)) {
305 pr_err("%s: main driver probe failed", __func__); 306 pr_err("%s: main driver probe failed", __func__);
306 return PTR_ERR(priv); 307 return PTR_ERR(priv);
307 } 308 }
308 309
309 /* Get MAC address if available (DT) */ 310 /* Get MAC address if available (DT) */
310 if (mac) 311 if (mac)
311 memcpy(priv->dev->dev_addr, mac, ETH_ALEN); 312 memcpy(priv->dev->dev_addr, mac, ETH_ALEN);
312 313
313 /* Get the MAC information */ 314 /* Get the MAC information */
314 priv->dev->irq = platform_get_irq_byname(pdev, "macirq"); 315 priv->dev->irq = platform_get_irq_byname(pdev, "macirq");
315 if (priv->dev->irq < 0) { 316 if (priv->dev->irq < 0) {
316 if (priv->dev->irq != -EPROBE_DEFER) { 317 if (priv->dev->irq != -EPROBE_DEFER) {
317 netdev_err(priv->dev, 318 netdev_err(priv->dev,
318 "MAC IRQ configuration information not found\n"); 319 "MAC IRQ configuration information not found\n");
319 } 320 }
320 return priv->dev->irq; 321 return priv->dev->irq;
321 } 322 }
322 323
323 /* 324 /*
324 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq 325 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
325 * The external wake up irq can be passed through the platform code 326 * The external wake up irq can be passed through the platform code
326 * named as "eth_wake_irq" 327 * named as "eth_wake_irq"
327 * 328 *
328 * In case the wake up interrupt is not passed from the platform 329 * In case the wake up interrupt is not passed from the platform
329 * so the driver will continue to use the mac irq (ndev->irq) 330 * so the driver will continue to use the mac irq (ndev->irq)
330 */ 331 */
331 priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); 332 priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
332 if (priv->wol_irq < 0) { 333 if (priv->wol_irq < 0) {
333 if (priv->wol_irq == -EPROBE_DEFER) 334 if (priv->wol_irq == -EPROBE_DEFER)
334 return -EPROBE_DEFER; 335 return -EPROBE_DEFER;
335 priv->wol_irq = priv->dev->irq; 336 priv->wol_irq = priv->dev->irq;
336 } 337 }
337 338
338 priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); 339 priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
339 if (priv->lpi_irq == -EPROBE_DEFER) 340 if (priv->lpi_irq == -EPROBE_DEFER)
340 return -EPROBE_DEFER; 341 return -EPROBE_DEFER;
341 342
342 platform_set_drvdata(pdev, priv->dev); 343 platform_set_drvdata(pdev, priv->dev);
343 344
344 pr_debug("STMMAC platform driver registration completed"); 345 pr_debug("STMMAC platform driver registration completed");
345 346
346 return 0; 347 return 0;
347 } 348 }
348 349
349 /** 350 /**
350 * stmmac_pltfr_remove 351 * stmmac_pltfr_remove
351 * @pdev: platform device pointer 352 * @pdev: platform device pointer
352 * Description: this function calls the main to free the net resources 353 * Description: this function calls the main to free the net resources
353 * and calls the platforms hook and release the resources (e.g. mem). 354 * and calls the platforms hook and release the resources (e.g. mem).
354 */ 355 */
355 static int stmmac_pltfr_remove(struct platform_device *pdev) 356 static int stmmac_pltfr_remove(struct platform_device *pdev)
356 { 357 {
357 struct net_device *ndev = platform_get_drvdata(pdev); 358 struct net_device *ndev = platform_get_drvdata(pdev);
358 struct stmmac_priv *priv = netdev_priv(ndev); 359 struct stmmac_priv *priv = netdev_priv(ndev);
359 int ret = stmmac_dvr_remove(ndev); 360 int ret = stmmac_dvr_remove(ndev);
360 361
361 if (priv->plat->exit) 362 if (priv->plat->exit)
362 priv->plat->exit(pdev, priv->plat->bsp_priv); 363 priv->plat->exit(pdev, priv->plat->bsp_priv);
363 364
364 if (priv->plat->free) 365 if (priv->plat->free)
365 priv->plat->free(pdev, priv->plat->bsp_priv); 366 priv->plat->free(pdev, priv->plat->bsp_priv);
366 367
367 return ret; 368 return ret;
368 } 369 }
369 370
370 #ifdef CONFIG_PM 371 #ifdef CONFIG_PM
371 static int stmmac_pltfr_suspend(struct device *dev) 372 static int stmmac_pltfr_suspend(struct device *dev)
372 { 373 {
373 int ret; 374 int ret;
374 struct net_device *ndev = dev_get_drvdata(dev); 375 struct net_device *ndev = dev_get_drvdata(dev);
375 struct stmmac_priv *priv = netdev_priv(ndev); 376 struct stmmac_priv *priv = netdev_priv(ndev);
376 struct platform_device *pdev = to_platform_device(dev); 377 struct platform_device *pdev = to_platform_device(dev);
377 378
378 ret = stmmac_suspend(ndev); 379 ret = stmmac_suspend(ndev);
379 if (priv->plat->exit) 380 if (priv->plat->exit)
380 priv->plat->exit(pdev, priv->plat->bsp_priv); 381 priv->plat->exit(pdev, priv->plat->bsp_priv);
381 382
382 return ret; 383 return ret;
383 } 384 }
384 385
385 static int stmmac_pltfr_resume(struct device *dev) 386 static int stmmac_pltfr_resume(struct device *dev)
386 { 387 {
387 struct net_device *ndev = dev_get_drvdata(dev); 388 struct net_device *ndev = dev_get_drvdata(dev);
388 struct stmmac_priv *priv = netdev_priv(ndev); 389 struct stmmac_priv *priv = netdev_priv(ndev);
389 struct platform_device *pdev = to_platform_device(dev); 390 struct platform_device *pdev = to_platform_device(dev);
390 391
391 if (priv->plat->init) 392 if (priv->plat->init)
392 priv->plat->init(pdev, priv->plat->bsp_priv); 393 priv->plat->init(pdev, priv->plat->bsp_priv);
393 394
394 return stmmac_resume(ndev); 395 return stmmac_resume(ndev);
395 } 396 }
396 397
397 #endif /* CONFIG_PM */ 398 #endif /* CONFIG_PM */
398 399
399 static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, 400 static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
400 stmmac_pltfr_suspend, stmmac_pltfr_resume); 401 stmmac_pltfr_suspend, stmmac_pltfr_resume);
401 402
402 struct platform_driver stmmac_pltfr_driver = { 403 struct platform_driver stmmac_pltfr_driver = {
403 .probe = stmmac_pltfr_probe, 404 .probe = stmmac_pltfr_probe,
404 .remove = stmmac_pltfr_remove, 405 .remove = stmmac_pltfr_remove,
405 .driver = { 406 .driver = {
406 .name = STMMAC_RESOURCE_NAME, 407 .name = STMMAC_RESOURCE_NAME,
407 .owner = THIS_MODULE, 408 .owner = THIS_MODULE,
408 .pm = &stmmac_pltfr_pm_ops, 409 .pm = &stmmac_pltfr_pm_ops,
409 .of_match_table = of_match_ptr(stmmac_dt_ids), 410 .of_match_table = of_match_ptr(stmmac_dt_ids),
410 }, 411 },
411 }; 412 };
412 413
413 MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver"); 414 MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver");
414 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 415 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
415 MODULE_LICENSE("GPL"); 416 MODULE_LICENSE("GPL");
416 417