diff options
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/mdio-gpio.c | 2 | ||||
-rw-r--r-- | drivers/net/phy/mdio-mux-gpio.c | 2 | ||||
-rw-r--r-- | drivers/net/phy/mdio-mux-mmioreg.c | 2 | ||||
-rw-r--r-- | drivers/net/phy/mdio-octeon.c | 4 | ||||
-rw-r--r-- | drivers/net/phy/mdio-sun4i.c | 18 | ||||
-rw-r--r-- | drivers/net/phy/micrel.c | 105 | ||||
-rw-r--r-- | drivers/net/phy/realtek.c | 4 |
7 files changed, 119 insertions, 18 deletions
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index a47f9236d966..8004acbef2c9 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -191,7 +191,7 @@ static int mdio_gpio_probe(struct platform_device *pdev) pdata = mdio_gpio_of_get_data(pdev); bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); } else { - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); bus_id = pdev->id; } diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c index e91d7d736ae2..d2dd9e473e2c 100644 --- a/drivers/net/phy/mdio-mux-gpio.c +++ b/drivers/net/phy/mdio-mux-gpio.c @@ -106,7 +106,7 @@ err: static int mdio_mux_gpio_remove(struct platform_device *pdev) { - struct mdio_mux_gpio_state *s = pdev->dev.platform_data; + struct mdio_mux_gpio_state *s = dev_get_platdata(&pdev->dev); mdio_mux_uninit(s->mux_handle); return 0; } diff --git a/drivers/net/phy/mdio-mux-mmioreg.c b/drivers/net/phy/mdio-mux-mmioreg.c index 9733bd239a86..f8e305d8da76 100644 --- a/drivers/net/phy/mdio-mux-mmioreg.c +++ b/drivers/net/phy/mdio-mux-mmioreg.c @@ -48,7 +48,7 @@ static int mdio_mux_mmioreg_switch_fn(int current_child, int desired_child, struct mdio_mux_mmioreg_state *s = data; if (current_child ^ desired_child) { - void *p = ioremap(s->phys, 1); + void __iomem *p = ioremap(s->phys, 1); uint8_t x, y; if (!p) diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c index b51fa1f469b0..6aee02ed97ac 100644 --- a/drivers/net/phy/mdio-octeon.c +++ b/drivers/net/phy/mdio-octeon.c @@ -222,7 +222,7 @@ static int octeon_mdiobus_probe(struct platform_device *pdev) bus->mii_bus->read = octeon_mdiobus_read; bus->mii_bus->write = octeon_mdiobus_write; - dev_set_drvdata(&pdev->dev, bus); + platform_set_drvdata(pdev, bus); err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node); if (err) @@ -244,7 +244,7 @@ static int octeon_mdiobus_remove(struct platform_device *pdev) struct octeon_mdiobus *bus; union cvmx_smix_en smi_en; - bus = dev_get_drvdata(&pdev->dev); + bus = platform_get_drvdata(pdev); mdiobus_unregister(bus->mii_bus); mdiobus_free(bus->mii_bus); diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c index 7f25e49ae37f..18969b3ad8bb 100644 --- a/drivers/net/phy/mdio-sun4i.c +++ b/drivers/net/phy/mdio-sun4i.c @@ -101,6 +101,7 @@ static int sun4i_mdio_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct mii_bus *bus; struct sun4i_mdio_data *data; + struct resource *res; int ret, i; bus = mdiobus_alloc_size(sizeof(*data)); @@ -114,7 +115,8 @@ static int sun4i_mdio_probe(struct platform_device *pdev) snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev)); bus->parent = &pdev->dev; - bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + bus->irq = devm_kzalloc(&pdev->dev, sizeof(int) * PHY_MAX_ADDR, + GFP_KERNEL); if (!bus->irq) { ret = -ENOMEM; goto err_out_free_mdiobus; @@ -124,10 +126,11 @@ static int sun4i_mdio_probe(struct platform_device *pdev) bus->irq[i] = PHY_POLL; data = bus->priv; - data->membase = of_iomap(np, 0); - if (!data->membase) { - ret = -ENOMEM; - goto err_out_free_mdio_irq; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(data->membase)) { + ret = PTR_ERR(data->membase); + goto err_out_free_mdiobus; } data->regulator = devm_regulator_get(&pdev->dev, "phy"); @@ -139,7 +142,7 @@ static int sun4i_mdio_probe(struct platform_device *pdev) } else { ret = regulator_enable(data->regulator); if (ret) - goto err_out_free_mdio_irq; + goto err_out_free_mdiobus; } ret = of_mdiobus_register(bus, np); @@ -152,8 +155,6 @@ static int sun4i_mdio_probe(struct platform_device *pdev) err_out_disable_regulator: regulator_disable(data->regulator); -err_out_free_mdio_irq: - kfree(bus->irq); err_out_free_mdiobus: mdiobus_free(bus); return ret; @@ -164,7 +165,6 @@ static int sun4i_mdio_remove(struct platform_device *pdev) struct mii_bus *bus = platform_get_drvdata(pdev); mdiobus_unregister(bus); - kfree(bus->irq); mdiobus_free(bus); return 0; diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 2510435f34ed..c31aad0004cb 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/phy.h> #include <linux/micrel_phy.h> +#include <linux/of.h> /* Operation Mode Strap Override */ #define MII_KSZPHY_OMSO 0x16 @@ -53,6 +54,20 @@ #define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) #define KSZ8051_RMII_50MHZ_CLK (1 << 7) +/* Write/read to/from extended registers */ +#define MII_KSZPHY_EXTREG 0x0b +#define KSZPHY_EXTREG_WRITE 0x8000 + +#define MII_KSZPHY_EXTREG_WRITE 0x0c +#define MII_KSZPHY_EXTREG_READ 0x0d + +/* Extended registers */ +#define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104 +#define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105 +#define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106 + +#define PS_TO_REG 200 + static int ksz_config_flags(struct phy_device *phydev) { int regval; @@ -65,6 +80,20 @@ static int ksz_config_flags(struct phy_device *phydev) return 0; } +static int kszphy_extended_write(struct phy_device *phydev, + u32 regnum, u16 val) +{ + phy_write(phydev, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | regnum); + return phy_write(phydev, MII_KSZPHY_EXTREG_WRITE, val); +} + +static int kszphy_extended_read(struct phy_device *phydev, + u32 regnum) +{ + phy_write(phydev, MII_KSZPHY_EXTREG, regnum); + return phy_read(phydev, MII_KSZPHY_EXTREG_READ); +} + static int kszphy_ack_interrupt(struct phy_device *phydev) { /* bit[7..0] int status, which is a read and clear register. */ @@ -141,10 +170,82 @@ static int ks8051_config_init(struct phy_device *phydev) return rc < 0 ? rc : 0; } +static int ksz9021_load_values_from_of(struct phy_device *phydev, + struct device_node *of_node, u16 reg, + char *field1, char *field2, + char *field3, char *field4) +{ + int val1 = -1; + int val2 = -2; + int val3 = -3; + int val4 = -4; + int newval; + int matches = 0; + + if (!of_property_read_u32(of_node, field1, &val1)) + matches++; + + if (!of_property_read_u32(of_node, field2, &val2)) + matches++; + + if (!of_property_read_u32(of_node, field3, &val3)) + matches++; + + if (!of_property_read_u32(of_node, field4, &val4)) + matches++; + + if (!matches) + return 0; + + if (matches < 4) + newval = kszphy_extended_read(phydev, reg); + else + newval = 0; + + if (val1 != -1) + newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0); + + if (val2 != -1) + newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4); + + if (val3 != -1) + newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8); + + if (val4 != -1) + newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12); + + return kszphy_extended_write(phydev, reg, newval); +} + +static int ksz9021_config_init(struct phy_device *phydev) +{ + struct device *dev = &phydev->dev; + struct device_node *of_node = dev->of_node; + + if (!of_node && dev->parent->of_node) + of_node = dev->parent->of_node; + + if (of_node) { + ksz9021_load_values_from_of(phydev, of_node, + MII_KSZPHY_CLK_CONTROL_PAD_SKEW, + "txen-skew-ps", "txc-skew-ps", + "rxdv-skew-ps", "rxc-skew-ps"); + ksz9021_load_values_from_of(phydev, of_node, + MII_KSZPHY_RX_DATA_PAD_SKEW, + "rxd0-skew-ps", "rxd1-skew-ps", + "rxd2-skew-ps", "rxd3-skew-ps"); + ksz9021_load_values_from_of(phydev, of_node, + MII_KSZPHY_TX_DATA_PAD_SKEW, + "txd0-skew-ps", "txd1-skew-ps", + "txd2-skew-ps", "txd3-skew-ps"); + } + return 0; +} + #define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 #define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6) #define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4) -int ksz8873mll_read_status(struct phy_device *phydev) +static int ksz8873mll_read_status(struct phy_device *phydev) { int regval; @@ -281,7 +382,7 @@ static struct phy_driver ksphy_driver[] = { .name = "Micrel KSZ9021 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init, + .config_init = ksz9021_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 8e7af8354342..138de837977f 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -23,7 +23,7 @@ #define RTL821x_INER_INIT 0x6400 #define RTL821x_INSR 0x13 -#define RTL8211E_INER_LINK_STAT 0x10 +#define RTL8211E_INER_LINK_STATUS 0x400 MODULE_DESCRIPTION("Realtek PHY driver"); MODULE_AUTHOR("Johnson Leung"); @@ -57,7 +57,7 @@ static int rtl8211e_config_intr(struct phy_device *phydev) if (phydev->interrupts == PHY_INTERRUPT_ENABLED) err = phy_write(phydev, RTL821x_INER, - RTL8211E_INER_LINK_STAT); + RTL8211E_INER_LINK_STATUS); else err = phy_write(phydev, RTL821x_INER, 0); |