X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/5be08769f35ba9a5c170eb7a1139f7778a2549a1..451654dc3a2ab82061493527e5f95cd3b9f0ac1a:/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c index d3cbacedb..b2460d726 100644 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c +++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c @@ -1,7 +1,7 @@ /* * Atheros AR71xx built-in ethernet mac driver * - * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008-2010 Gabor Juhos * Copyright (C) 2008 Imre Kaloz * * Based on Atheros' AG7100 driver @@ -16,8 +16,6 @@ #define AG71XX_MDIO_RETRY 1000 #define AG71XX_MDIO_DELAY 5 -struct ag71xx_mdio *ag71xx_mdio_bus; - static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, u32 value) { @@ -49,7 +47,7 @@ static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); } -static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) +int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) { int ret; int i; @@ -75,12 +73,11 @@ static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); - out: +out: return ret; } -static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, - int addr, int reg, u16 val) +void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val) { int i; @@ -106,7 +103,10 @@ static int ag71xx_mdio_reset(struct mii_bus *bus) struct ag71xx_mdio *am = bus->priv; u32 t; - t = MII_CFG_CLK_DIV_28; + if (am->pdata->is_ar7240) + t = MII_CFG_CLK_DIV_6; + else + t = MII_CFG_CLK_DIV_28; ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); udelay(100); @@ -121,18 +121,24 @@ static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) { struct ag71xx_mdio *am = bus->priv; - return ag71xx_mdio_mii_read(am, addr, reg); + if (am->pdata->is_ar7240) + return ar7240sw_phy_read(bus, addr, reg); + else + return ag71xx_mdio_mii_read(am, addr, reg); } static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) { struct ag71xx_mdio *am = bus->priv; - ag71xx_mdio_mii_write(am, addr, reg, val); + if (am->pdata->is_ar7240) + ar7240sw_phy_write(bus, addr, reg, val); + else + ag71xx_mdio_mii_write(am, addr, reg, val); return 0; } -static int __init ag71xx_mdio_probe(struct platform_device *pdev) +static int __devinit ag71xx_mdio_probe(struct platform_device *pdev) { struct ag71xx_mdio_platform_data *pdata; struct ag71xx_mdio *am; @@ -140,8 +146,11 @@ static int __init ag71xx_mdio_probe(struct platform_device *pdev) int i; int err; - if (ag71xx_mdio_bus) - return -EBUSY; + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data specified\n"); + return -EINVAL; + } am = kzalloc(sizeof(*am), GFP_KERNEL); if (!am) { @@ -149,6 +158,8 @@ static int __init ag71xx_mdio_probe(struct platform_device *pdev) goto err_out; } + am->pdata = pdata; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no iomem resource found\n"); @@ -176,11 +187,8 @@ static int __init ag71xx_mdio_probe(struct platform_device *pdev) am->mii_bus->irq = am->mii_irq; am->mii_bus->priv = am; am->mii_bus->parent = &pdev->dev; - snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); - - pdata = pdev->dev.platform_data; - if (pdata) - am->mii_bus->phy_mask = pdata->phy_mask; + snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); + am->mii_bus->phy_mask = pdata->phy_mask; for (i = 0; i < PHY_MAX_ADDR; i++) am->mii_irq[i] = PHY_POLL; @@ -194,25 +202,23 @@ static int __init ag71xx_mdio_probe(struct platform_device *pdev) ag71xx_mdio_dump_regs(am); platform_set_drvdata(pdev, am); - ag71xx_mdio_bus = am; return 0; - err_free_bus: +err_free_bus: mdiobus_free(am->mii_bus); - err_iounmap: +err_iounmap: iounmap(am->mdio_base); - err_free_mdio: +err_free_mdio: kfree(am); - err_out: +err_out: return err; } -static int __exit ag71xx_mdio_remove(struct platform_device *pdev) +static int __devexit ag71xx_mdio_remove(struct platform_device *pdev) { struct ag71xx_mdio *am = platform_get_drvdata(pdev); if (am) { - ag71xx_mdio_bus = NULL; mdiobus_unregister(am->mii_bus); mdiobus_free(am->mii_bus); iounmap(am->mdio_base); @@ -231,7 +237,7 @@ static struct platform_driver ag71xx_mdio_driver = { } }; -int ag71xx_mdio_driver_init(void) +int __init ag71xx_mdio_driver_init(void) { return platform_driver_register(&ag71xx_mdio_driver); }