aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Fainelli <florian@openwrt.org>2013-03-21 23:39:28 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-22 10:25:15 -0400
commitc3a07134e6aa5b93a37f72ffa3d11fadf72bf757 (patch)
treee61bf96df027d188c5b07722911121ec1186e701
parent2ec985213864cb64c45dc0284d7316142eefb5d4 (diff)
mv643xx_eth: convert to use the Marvell Orion MDIO driver
This patch converts the Marvell MV643XX ethernet driver to use the Marvell Orion MDIO driver. As a result, PowerPC and ARM platforms registering the Marvell MV643XX ethernet driver are also updated to register a Marvell Orion MDIO driver. This driver voluntarily overlaps with the Marvell Ethernet shared registers because it will use a subset of this shared register (shared_base + 0x4 to shared_base + 0x84). The Ethernet driver is also updated to look up for a PHY device using the Orion MDIO bus driver. For ARM and PowerPC we register a single instance of the "mvmdio" driver in the system like it used to be done with the use of the "shared_smi" platform_data cookie on ARM. Note that it is safe to register the mvmdio driver only for the "ge00" instance of the driver because this "ge00" interface is guaranteed to always be explicitely registered by consumers of arch/arm/plat-orion/common.c and other instances (ge01, ge10 and ge11) were all pointing their shared_smi to ge00. For PowerPC the in-tree Device Tree Source files mention only one MV643XX ethernet MAC instance so the MDIO bus driver is registered only when id == 0. Signed-off-by: Florian Fainelli <florian@openwrt.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/arm/plat-orion/common.c54
-rw-r--r--arch/powerpc/platforms/chrp/pegasos_eth.c20
-rw-r--r--arch/powerpc/sysdev/mv64x60_dev.c16
-rw-r--r--drivers/net/ethernet/marvell/Kconfig5
-rw-r--r--drivers/net/ethernet/marvell/Makefile2
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c195
-rw-r--r--include/linux/mv643xx_eth.h1
7 files changed, 84 insertions, 209 deletions
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 2d4b6414609f..251f827271e9 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -238,6 +238,7 @@ static __init void ge_complete(
238 struct mv643xx_eth_shared_platform_data *orion_ge_shared_data, 238 struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
239 struct resource *orion_ge_resource, unsigned long irq, 239 struct resource *orion_ge_resource, unsigned long irq,
240 struct platform_device *orion_ge_shared, 240 struct platform_device *orion_ge_shared,
241 struct platform_device *orion_ge_mvmdio,
241 struct mv643xx_eth_platform_data *eth_data, 242 struct mv643xx_eth_platform_data *eth_data,
242 struct platform_device *orion_ge) 243 struct platform_device *orion_ge)
243{ 244{
@@ -247,6 +248,8 @@ static __init void ge_complete(
247 orion_ge->dev.platform_data = eth_data; 248 orion_ge->dev.platform_data = eth_data;
248 249
249 platform_device_register(orion_ge_shared); 250 platform_device_register(orion_ge_shared);
251 if (orion_ge_mvmdio)
252 platform_device_register(orion_ge_mvmdio);
250 platform_device_register(orion_ge); 253 platform_device_register(orion_ge);
251} 254}
252 255
@@ -258,8 +261,6 @@ struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
258static struct resource orion_ge00_shared_resources[] = { 261static struct resource orion_ge00_shared_resources[] = {
259 { 262 {
260 .name = "ge00 base", 263 .name = "ge00 base",
261 }, {
262 .name = "ge00 err irq",
263 }, 264 },
264}; 265};
265 266
@@ -271,6 +272,19 @@ static struct platform_device orion_ge00_shared = {
271 }, 272 },
272}; 273};
273 274
275static struct resource orion_ge_mvmdio_resources[] = {
276 {
277 .name = "ge00 mvmdio base",
278 }, {
279 .name = "ge00 mvmdio err irq",
280 },
281};
282
283static struct platform_device orion_ge_mvmdio = {
284 .name = "orion-mdio",
285 .id = -1,
286};
287
274static struct resource orion_ge00_resources[] = { 288static struct resource orion_ge00_resources[] = {
275 { 289 {
276 .name = "ge00 irq", 290 .name = "ge00 irq",
@@ -295,26 +309,25 @@ void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
295 unsigned int tx_csum_limit) 309 unsigned int tx_csum_limit)
296{ 310{
297 fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, 311 fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
298 mapbase + 0x2000, SZ_16K - 1, irq_err); 312 mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
313 fill_resources(&orion_ge_mvmdio, orion_ge_mvmdio_resources,
314 mapbase + 0x2004, 0x84 - 1, irq_err);
299 orion_ge00_shared_data.tx_csum_limit = tx_csum_limit; 315 orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;
300 ge_complete(&orion_ge00_shared_data, 316 ge_complete(&orion_ge00_shared_data,
301 orion_ge00_resources, irq, &orion_ge00_shared, 317 orion_ge00_resources, irq, &orion_ge00_shared,
318 &orion_ge_mvmdio,
302 eth_data, &orion_ge00); 319 eth_data, &orion_ge00);
303} 320}
304 321
305/***************************************************************************** 322/*****************************************************************************
306 * GE01 323 * GE01
307 ****************************************************************************/ 324 ****************************************************************************/
308struct mv643xx_eth_shared_platform_data orion_ge01_shared_data = { 325struct mv643xx_eth_shared_platform_data orion_ge01_shared_data;
309 .shared_smi = &orion_ge00_shared,
310};
311 326
312static struct resource orion_ge01_shared_resources[] = { 327static struct resource orion_ge01_shared_resources[] = {
313 { 328 {
314 .name = "ge01 base", 329 .name = "ge01 base",
315 }, { 330 }
316 .name = "ge01 err irq",
317 },
318}; 331};
319 332
320static struct platform_device orion_ge01_shared = { 333static struct platform_device orion_ge01_shared = {
@@ -349,26 +362,23 @@ void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
349 unsigned int tx_csum_limit) 362 unsigned int tx_csum_limit)
350{ 363{
351 fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, 364 fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
352 mapbase + 0x2000, SZ_16K - 1, irq_err); 365 mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
353 orion_ge01_shared_data.tx_csum_limit = tx_csum_limit; 366 orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;
354 ge_complete(&orion_ge01_shared_data, 367 ge_complete(&orion_ge01_shared_data,
355 orion_ge01_resources, irq, &orion_ge01_shared, 368 orion_ge01_resources, irq, &orion_ge01_shared,
369 NULL,
356 eth_data, &orion_ge01); 370 eth_data, &orion_ge01);
357} 371}
358 372
359/***************************************************************************** 373/*****************************************************************************
360 * GE10 374 * GE10
361 ****************************************************************************/ 375 ****************************************************************************/
362struct mv643xx_eth_shared_platform_data orion_ge10_shared_data = { 376struct mv643xx_eth_shared_platform_data orion_ge10_shared_data;
363 .shared_smi = &orion_ge00_shared,
364};
365 377
366static struct resource orion_ge10_shared_resources[] = { 378static struct resource orion_ge10_shared_resources[] = {
367 { 379 {
368 .name = "ge10 base", 380 .name = "ge10 base",
369 }, { 381 }
370 .name = "ge10 err irq",
371 },
372}; 382};
373 383
374static struct platform_device orion_ge10_shared = { 384static struct platform_device orion_ge10_shared = {
@@ -402,24 +412,21 @@ void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
402 unsigned long irq_err) 412 unsigned long irq_err)
403{ 413{
404 fill_resources(&orion_ge10_shared, orion_ge10_shared_resources, 414 fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
405 mapbase + 0x2000, SZ_16K - 1, irq_err); 415 mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
406 ge_complete(&orion_ge10_shared_data, 416 ge_complete(&orion_ge10_shared_data,
407 orion_ge10_resources, irq, &orion_ge10_shared, 417 orion_ge10_resources, irq, &orion_ge10_shared,
418 NULL,
408 eth_data, &orion_ge10); 419 eth_data, &orion_ge10);
409} 420}
410 421
411/***************************************************************************** 422/*****************************************************************************
412 * GE11 423 * GE11
413 ****************************************************************************/ 424 ****************************************************************************/
414struct mv643xx_eth_shared_platform_data orion_ge11_shared_data = { 425struct mv643xx_eth_shared_platform_data orion_ge11_shared_data;
415 .shared_smi = &orion_ge00_shared,
416};
417 426
418static struct resource orion_ge11_shared_resources[] = { 427static struct resource orion_ge11_shared_resources[] = {
419 { 428 {
420 .name = "ge11 base", 429 .name = "ge11 base",
421 }, {
422 .name = "ge11 err irq",
423 }, 430 },
424}; 431};
425 432
@@ -454,9 +461,10 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
454 unsigned long irq_err) 461 unsigned long irq_err)
455{ 462{
456 fill_resources(&orion_ge11_shared, orion_ge11_shared_resources, 463 fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
457 mapbase + 0x2000, SZ_16K - 1, irq_err); 464 mapbase + 0x2000, SZ_16K - 1, NO_IRQ);
458 ge_complete(&orion_ge11_shared_data, 465 ge_complete(&orion_ge11_shared_data,
459 orion_ge11_resources, irq, &orion_ge11_shared, 466 orion_ge11_resources, irq, &orion_ge11_shared,
467 NULL,
460 eth_data, &orion_ge11); 468 eth_data, &orion_ge11);
461} 469}
462 470
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 039fc8e82199..2b4dc6abde6c 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -47,6 +47,25 @@ static struct platform_device mv643xx_eth_shared_device = {
47 .resource = mv643xx_eth_shared_resources, 47 .resource = mv643xx_eth_shared_resources,
48}; 48};
49 49
50/*
51 * The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1
52 */
53static struct resource mv643xx_eth_mvmdio_resources[] = {
54 [0] = {
55 .name = "ethernet mdio base",
56 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4,
57 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83,
58 .flags = IORESOURCE_MEM,
59 },
60};
61
62static struct platform_device mv643xx_eth_mvmdio_device = {
63 .name = "orion-mdio",
64 .id = -1,
65 .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources),
66 .resource = mv643xx_eth_shared_resources,
67};
68
50static struct resource mv643xx_eth_port1_resources[] = { 69static struct resource mv643xx_eth_port1_resources[] = {
51 [0] = { 70 [0] = {
52 .name = "eth port1 irq", 71 .name = "eth port1 irq",
@@ -82,6 +101,7 @@ static struct platform_device eth_port1_device = {
82 101
83static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { 102static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
84 &mv643xx_eth_shared_device, 103 &mv643xx_eth_shared_device,
104 &mv643xx_eth_mvmdio_device,
85 &eth_port1_device, 105 &eth_port1_device,
86}; 106};
87 107
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 0f6af41ebb44..4a25c26f0bf4 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -214,15 +214,27 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev(
214 struct device_node *np, int id) 214 struct device_node *np, int id)
215{ 215{
216 struct platform_device *pdev; 216 struct platform_device *pdev;
217 struct resource r[1]; 217 struct resource r[2];
218 int err; 218 int err;
219 219
220 err = of_address_to_resource(np, 0, &r[0]); 220 err = of_address_to_resource(np, 0, &r[0]);
221 if (err) 221 if (err)
222 return ERR_PTR(err); 222 return ERR_PTR(err);
223 223
224 /* register an orion mdio bus driver */
225 r[1].start = r[0].start + 0x4;
226 r[1].end = r[0].start + 0x84 - 1;
227 r[1].flags = IORESOURCE_MEM;
228
229 if (id == 0) {
230 pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1);
231 if (!pdev)
232 return pdev;
233 }
234
224 pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, 235 pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id,
225 r, 1); 236 &r[0], 1);
237
226 return pdev; 238 return pdev;
227} 239}
228 240
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index edfba9370922..5170ecb00acc 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -23,6 +23,7 @@ config MV643XX_ETH
23 depends on (MV64X60 || PPC32 || PLAT_ORION) && INET 23 depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
24 select INET_LRO 24 select INET_LRO
25 select PHYLIB 25 select PHYLIB
26 select MVMDIO
26 ---help--- 27 ---help---
27 This driver supports the gigabit ethernet MACs in the 28 This driver supports the gigabit ethernet MACs in the
28 Marvell Discovery PPC/MIPS chipset family (MV643XX) and 29 Marvell Discovery PPC/MIPS chipset family (MV643XX) and
@@ -38,9 +39,7 @@ config MVMDIO
38 interface units of the Marvell EBU SoCs (Kirkwood, Orion5x, 39 interface units of the Marvell EBU SoCs (Kirkwood, Orion5x,
39 Dove, Armada 370 and Armada XP). 40 Dove, Armada 370 and Armada XP).
40 41
41 For now, this driver is only needed for the MVNETA driver 42 This driver is used by the MV643XX_ETH and MVNETA drivers.
42 (used on Armada 370 and XP), but it could be used in the
43 future by the MV643XX_ETH driver.
44 43
45config MVNETA 44config MVNETA
46 tristate "Marvell Armada 370/XP network interface support" 45 tristate "Marvell Armada 370/XP network interface support"
diff --git a/drivers/net/ethernet/marvell/Makefile b/drivers/net/ethernet/marvell/Makefile
index 7f63b4aac434..5c4a7765ff0e 100644
--- a/drivers/net/ethernet/marvell/Makefile
+++ b/drivers/net/ethernet/marvell/Makefile
@@ -2,8 +2,8 @@
2# Makefile for the Marvell device drivers. 2# Makefile for the Marvell device drivers.
3# 3#
4 4
5obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
6obj-$(CONFIG_MVMDIO) += mvmdio.o 5obj-$(CONFIG_MVMDIO) += mvmdio.o
6obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
7obj-$(CONFIG_MVNETA) += mvneta.o 7obj-$(CONFIG_MVNETA) += mvneta.o
8obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o 8obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
9obj-$(CONFIG_SKGE) += skge.o 9obj-$(CONFIG_SKGE) += skge.o
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index d1ecf4bf7da7..a65a92ef19ec 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -69,14 +69,6 @@ static char mv643xx_eth_driver_version[] = "1.4";
69 * Registers shared between all ports. 69 * Registers shared between all ports.
70 */ 70 */
71#define PHY_ADDR 0x0000 71#define PHY_ADDR 0x0000
72#define SMI_REG 0x0004
73#define SMI_BUSY 0x10000000
74#define SMI_READ_VALID 0x08000000
75#define SMI_OPCODE_READ 0x04000000
76#define SMI_OPCODE_WRITE 0x00000000
77#define ERR_INT_CAUSE 0x0080
78#define ERR_INT_SMI_DONE 0x00000010
79#define ERR_INT_MASK 0x0084
80#define WINDOW_BASE(w) (0x0200 + ((w) << 3)) 72#define WINDOW_BASE(w) (0x0200 + ((w) << 3))
81#define WINDOW_SIZE(w) (0x0204 + ((w) << 3)) 73#define WINDOW_SIZE(w) (0x0204 + ((w) << 3))
82#define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2)) 74#define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2))
@@ -266,25 +258,6 @@ struct mv643xx_eth_shared_private {
266 void __iomem *base; 258 void __iomem *base;
267 259
268 /* 260 /*
269 * Points at the right SMI instance to use.
270 */
271 struct mv643xx_eth_shared_private *smi;
272
273 /*
274 * Provides access to local SMI interface.
275 */
276 struct mii_bus *smi_bus;
277
278 /*
279 * If we have access to the error interrupt pin (which is
280 * somewhat misnamed as it not only reflects internal errors
281 * but also reflects SMI completion), use that to wait for
282 * SMI access completion instead of polling the SMI busy bit.
283 */
284 int err_interrupt;
285 wait_queue_head_t smi_busy_wait;
286
287 /*
288 * Per-port MBUS window access register value. 261 * Per-port MBUS window access register value.
289 */ 262 */
290 u32 win_protect; 263 u32 win_protect;
@@ -1122,97 +1095,6 @@ out_write:
1122 wrlp(mp, PORT_SERIAL_CONTROL, pscr); 1095 wrlp(mp, PORT_SERIAL_CONTROL, pscr);
1123} 1096}
1124 1097
1125static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
1126{
1127 struct mv643xx_eth_shared_private *msp = dev_id;
1128
1129 if (readl(msp->base + ERR_INT_CAUSE) & ERR_INT_SMI_DONE) {
1130 writel(~ERR_INT_SMI_DONE, msp->base + ERR_INT_CAUSE);
1131 wake_up(&msp->smi_busy_wait);
1132 return IRQ_HANDLED;
1133 }
1134
1135 return IRQ_NONE;
1136}
1137
1138static int smi_is_done(struct mv643xx_eth_shared_private *msp)
1139{
1140 return !(readl(msp->base + SMI_REG) & SMI_BUSY);
1141}
1142
1143static int smi_wait_ready(struct mv643xx_eth_shared_private *msp)
1144{
1145 if (msp->err_interrupt == NO_IRQ) {
1146 int i;
1147
1148 for (i = 0; !smi_is_done(msp); i++) {
1149 if (i == 10)
1150 return -ETIMEDOUT;
1151 msleep(10);
1152 }
1153
1154 return 0;
1155 }
1156
1157 if (!smi_is_done(msp)) {
1158 wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp),
1159 msecs_to_jiffies(100));
1160 if (!smi_is_done(msp))
1161 return -ETIMEDOUT;
1162 }
1163
1164 return 0;
1165}
1166
1167static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
1168{
1169 struct mv643xx_eth_shared_private *msp = bus->priv;
1170 void __iomem *smi_reg = msp->base + SMI_REG;
1171 int ret;
1172
1173 if (smi_wait_ready(msp)) {
1174 pr_warn("SMI bus busy timeout\n");
1175 return -ETIMEDOUT;
1176 }
1177
1178 writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);
1179
1180 if (smi_wait_ready(msp)) {
1181 pr_warn("SMI bus busy timeout\n");
1182 return -ETIMEDOUT;
1183 }
1184
1185 ret = readl(smi_reg);
1186 if (!(ret & SMI_READ_VALID)) {
1187 pr_warn("SMI bus read not valid\n");
1188 return -ENODEV;
1189 }
1190
1191 return ret & 0xffff;
1192}
1193
1194static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
1195{
1196 struct mv643xx_eth_shared_private *msp = bus->priv;
1197 void __iomem *smi_reg = msp->base + SMI_REG;
1198
1199 if (smi_wait_ready(msp)) {
1200 pr_warn("SMI bus busy timeout\n");
1201 return -ETIMEDOUT;
1202 }
1203
1204 writel(SMI_OPCODE_WRITE | (reg << 21) |
1205 (addr << 16) | (val & 0xffff), smi_reg);
1206
1207 if (smi_wait_ready(msp)) {
1208 pr_warn("SMI bus busy timeout\n");
1209 return -ETIMEDOUT;
1210 }
1211
1212 return 0;
1213}
1214
1215
1216/* statistics ***************************************************************/ 1098/* statistics ***************************************************************/
1217static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev) 1099static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
1218{ 1100{
@@ -2688,47 +2570,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
2688 goto out_free; 2570 goto out_free;
2689 2571
2690 /* 2572 /*
2691 * Set up and register SMI bus.
2692 */
2693 if (pd == NULL || pd->shared_smi == NULL) {
2694 msp->smi_bus = mdiobus_alloc();
2695 if (msp->smi_bus == NULL)
2696 goto out_unmap;
2697
2698 msp->smi_bus->priv = msp;
2699 msp->smi_bus->name = "mv643xx_eth smi";
2700 msp->smi_bus->read = smi_bus_read;
2701 msp->smi_bus->write = smi_bus_write,
2702 snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
2703 pdev->name, pdev->id);
2704 msp->smi_bus->parent = &pdev->dev;
2705 msp->smi_bus->phy_mask = 0xffffffff;
2706 if (mdiobus_register(msp->smi_bus) < 0)
2707 goto out_free_mii_bus;
2708 msp->smi = msp;
2709 } else {
2710 msp->smi = platform_get_drvdata(pd->shared_smi);
2711 }
2712
2713 msp->err_interrupt = NO_IRQ;
2714 init_waitqueue_head(&msp->smi_busy_wait);
2715
2716 /*
2717 * Check whether the error interrupt is hooked up.
2718 */
2719 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
2720 if (res != NULL) {
2721 int err;
2722
2723 err = request_irq(res->start, mv643xx_eth_err_irq,
2724 IRQF_SHARED, "mv643xx_eth", msp);
2725 if (!err) {
2726 writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK);
2727 msp->err_interrupt = res->start;
2728 }
2729 }
2730
2731 /*
2732 * (Re-)program MBUS remapping windows if we are asked to. 2573 * (Re-)program MBUS remapping windows if we are asked to.
2733 */ 2574 */
2734 dram = mv_mbus_dram_info(); 2575 dram = mv_mbus_dram_info();
@@ -2743,10 +2584,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
2743 2584
2744 return 0; 2585 return 0;
2745 2586
2746out_free_mii_bus:
2747 mdiobus_free(msp->smi_bus);
2748out_unmap:
2749 iounmap(msp->base);
2750out_free: 2587out_free:
2751 kfree(msp); 2588 kfree(msp);
2752out: 2589out:
@@ -2756,14 +2593,7 @@ out:
2756static int mv643xx_eth_shared_remove(struct platform_device *pdev) 2593static int mv643xx_eth_shared_remove(struct platform_device *pdev)
2757{ 2594{
2758 struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev); 2595 struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
2759 struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
2760 2596
2761 if (pd == NULL || pd->shared_smi == NULL) {
2762 mdiobus_unregister(msp->smi_bus);
2763 mdiobus_free(msp->smi_bus);
2764 }
2765 if (msp->err_interrupt != NO_IRQ)
2766 free_irq(msp->err_interrupt, msp);
2767 iounmap(msp->base); 2597 iounmap(msp->base);
2768 kfree(msp); 2598 kfree(msp);
2769 2599
@@ -2826,14 +2656,21 @@ static void set_params(struct mv643xx_eth_private *mp,
2826 mp->txq_count = pd->tx_queue_count ? : 1; 2656 mp->txq_count = pd->tx_queue_count ? : 1;
2827} 2657}
2828 2658
2659static void mv643xx_eth_adjust_link(struct net_device *dev)
2660{
2661 struct mv643xx_eth_private *mp = netdev_priv(dev);
2662
2663 mv643xx_adjust_pscr(mp);
2664}
2665
2829static struct phy_device *phy_scan(struct mv643xx_eth_private *mp, 2666static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
2830 int phy_addr) 2667 int phy_addr)
2831{ 2668{
2832 struct mii_bus *bus = mp->shared->smi->smi_bus;
2833 struct phy_device *phydev; 2669 struct phy_device *phydev;
2834 int start; 2670 int start;
2835 int num; 2671 int num;
2836 int i; 2672 int i;
2673 char phy_id[MII_BUS_ID_SIZE + 3];
2837 2674
2838 if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) { 2675 if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) {
2839 start = phy_addr_get(mp) & 0x1f; 2676 start = phy_addr_get(mp) & 0x1f;
@@ -2843,17 +2680,19 @@ static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
2843 num = 1; 2680 num = 1;
2844 } 2681 }
2845 2682
2683 /* Attempt to connect to the PHY using orion-mdio */
2846 phydev = NULL; 2684 phydev = NULL;
2847 for (i = 0; i < num; i++) { 2685 for (i = 0; i < num; i++) {
2848 int addr = (start + i) & 0x1f; 2686 int addr = (start + i) & 0x1f;
2849 2687
2850 if (bus->phy_map[addr] == NULL) 2688 snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
2851 mdiobus_scan(bus, addr); 2689 "orion-mdio-mii", addr);
2852 2690
2853 if (phydev == NULL) { 2691 phydev = phy_connect(mp->dev, phy_id, mv643xx_eth_adjust_link,
2854 phydev = bus->phy_map[addr]; 2692 PHY_INTERFACE_MODE_GMII);
2855 if (phydev != NULL) 2693 if (!IS_ERR(phydev)) {
2856 phy_addr_set(mp, addr); 2694 phy_addr_set(mp, addr);
2695 break;
2857 } 2696 }
2858 } 2697 }
2859 2698
@@ -2866,8 +2705,6 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
2866 2705
2867 phy_reset(mp); 2706 phy_reset(mp);
2868 2707
2869 phy_attach(mp->dev, dev_name(&phy->dev), PHY_INTERFACE_MODE_GMII);
2870
2871 if (speed == 0) { 2708 if (speed == 0) {
2872 phy->autoneg = AUTONEG_ENABLE; 2709 phy->autoneg = AUTONEG_ENABLE;
2873 phy->speed = 0; 2710 phy->speed = 0;
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
index 49258e0ed1c6..141d395bbb5f 100644
--- a/include/linux/mv643xx_eth.h
+++ b/include/linux/mv643xx_eth.h
@@ -19,7 +19,6 @@
19 19
20struct mv643xx_eth_shared_platform_data { 20struct mv643xx_eth_shared_platform_data {
21 struct mbus_dram_target_info *dram; 21 struct mbus_dram_target_info *dram;
22 struct platform_device *shared_smi;
23 /* 22 /*
24 * Max packet size for Tx IP/Layer 4 checksum, when set to 0, default 23 * Max packet size for Tx IP/Layer 4 checksum, when set to 0, default
25 * limit of 9KiB will be used. 24 * limit of 9KiB will be used.