diff options
| author | David S. Miller <davem@davemloft.net> | 2009-07-23 22:03:51 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-07-23 22:03:51 -0400 |
| commit | 74d154189d597b91da4322996dbf4f5c3d1544ab (patch) | |
| tree | 6f09861b5e2f875d2d8ea2127b16add9103221c6 /drivers/net/phy | |
| parent | 5a6338db37885af06760d40cad589316e48431e9 (diff) | |
| parent | ffafa60d496f80c250f2ae0340ae94434c0b0b4d (diff) | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/wireless/iwmc3200wifi/netdev.c
net/wireless/scan.c
Diffstat (limited to 'drivers/net/phy')
| -rw-r--r-- | drivers/net/phy/mdio-gpio.c | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 33984b737233..22cdd451fb82 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | #ifdef CONFIG_OF_GPIO | 31 | #ifdef CONFIG_OF_GPIO |
| 32 | #include <linux/of_gpio.h> | 32 | #include <linux/of_gpio.h> |
| 33 | #include <linux/of_mdio.h> | ||
| 33 | #include <linux/of_platform.h> | 34 | #include <linux/of_platform.h> |
| 34 | #endif | 35 | #endif |
| 35 | 36 | ||
| @@ -81,13 +82,12 @@ static struct mdiobb_ops mdio_gpio_ops = { | |||
| 81 | .get_mdio_data = mdio_get, | 82 | .get_mdio_data = mdio_get, |
| 82 | }; | 83 | }; |
| 83 | 84 | ||
| 84 | static int __devinit mdio_gpio_bus_init(struct device *dev, | 85 | static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev, |
| 85 | struct mdio_gpio_platform_data *pdata, | 86 | struct mdio_gpio_platform_data *pdata, |
| 86 | int bus_id) | 87 | int bus_id) |
| 87 | { | 88 | { |
| 88 | struct mii_bus *new_bus; | 89 | struct mii_bus *new_bus; |
| 89 | struct mdio_gpio_info *bitbang; | 90 | struct mdio_gpio_info *bitbang; |
| 90 | int ret = -ENOMEM; | ||
| 91 | int i; | 91 | int i; |
| 92 | 92 | ||
| 93 | bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); | 93 | bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); |
| @@ -104,8 +104,6 @@ static int __devinit mdio_gpio_bus_init(struct device *dev, | |||
| 104 | 104 | ||
| 105 | new_bus->name = "GPIO Bitbanged MDIO", | 105 | new_bus->name = "GPIO Bitbanged MDIO", |
| 106 | 106 | ||
| 107 | ret = -ENODEV; | ||
| 108 | |||
| 109 | new_bus->phy_mask = pdata->phy_mask; | 107 | new_bus->phy_mask = pdata->phy_mask; |
| 110 | new_bus->irq = pdata->irqs; | 108 | new_bus->irq = pdata->irqs; |
| 111 | new_bus->parent = dev; | 109 | new_bus->parent = dev; |
| @@ -129,15 +127,8 @@ static int __devinit mdio_gpio_bus_init(struct device *dev, | |||
| 129 | 127 | ||
| 130 | dev_set_drvdata(dev, new_bus); | 128 | dev_set_drvdata(dev, new_bus); |
| 131 | 129 | ||
| 132 | ret = mdiobus_register(new_bus); | 130 | return new_bus; |
| 133 | if (ret) | ||
| 134 | goto out_free_all; | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | 131 | ||
| 138 | out_free_all: | ||
| 139 | dev_set_drvdata(dev, NULL); | ||
| 140 | gpio_free(bitbang->mdio); | ||
| 141 | out_free_mdc: | 132 | out_free_mdc: |
| 142 | gpio_free(bitbang->mdc); | 133 | gpio_free(bitbang->mdc); |
| 143 | out_free_bus: | 134 | out_free_bus: |
| @@ -145,30 +136,47 @@ out_free_bus: | |||
| 145 | out_free_bitbang: | 136 | out_free_bitbang: |
| 146 | kfree(bitbang); | 137 | kfree(bitbang); |
| 147 | out: | 138 | out: |
| 148 | return ret; | 139 | return NULL; |
| 149 | } | 140 | } |
| 150 | 141 | ||
| 151 | static void __devexit mdio_gpio_bus_destroy(struct device *dev) | 142 | static void __devinit mdio_gpio_bus_deinit(struct device *dev) |
| 152 | { | 143 | { |
| 153 | struct mii_bus *bus = dev_get_drvdata(dev); | 144 | struct mii_bus *bus = dev_get_drvdata(dev); |
| 154 | struct mdio_gpio_info *bitbang = bus->priv; | 145 | struct mdio_gpio_info *bitbang = bus->priv; |
| 155 | 146 | ||
| 156 | mdiobus_unregister(bus); | ||
| 157 | free_mdio_bitbang(bus); | ||
| 158 | dev_set_drvdata(dev, NULL); | 147 | dev_set_drvdata(dev, NULL); |
| 159 | gpio_free(bitbang->mdc); | ||
| 160 | gpio_free(bitbang->mdio); | 148 | gpio_free(bitbang->mdio); |
| 149 | gpio_free(bitbang->mdc); | ||
| 150 | free_mdio_bitbang(bus); | ||
| 161 | kfree(bitbang); | 151 | kfree(bitbang); |
| 162 | } | 152 | } |
| 163 | 153 | ||
| 154 | static void __devexit mdio_gpio_bus_destroy(struct device *dev) | ||
| 155 | { | ||
| 156 | struct mii_bus *bus = dev_get_drvdata(dev); | ||
| 157 | |||
| 158 | mdiobus_unregister(bus); | ||
| 159 | mdio_gpio_bus_deinit(dev); | ||
| 160 | } | ||
| 161 | |||
| 164 | static int __devinit mdio_gpio_probe(struct platform_device *pdev) | 162 | static int __devinit mdio_gpio_probe(struct platform_device *pdev) |
| 165 | { | 163 | { |
| 166 | struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; | 164 | struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; |
| 165 | struct mii_bus *new_bus; | ||
| 166 | int ret; | ||
| 167 | 167 | ||
| 168 | if (!pdata) | 168 | if (!pdata) |
| 169 | return -ENODEV; | 169 | return -ENODEV; |
| 170 | 170 | ||
| 171 | return mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); | 171 | new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); |
| 172 | if (!new_bus) | ||
| 173 | return -ENODEV; | ||
| 174 | |||
| 175 | ret = mdiobus_register(new_bus); | ||
| 176 | if (ret) | ||
| 177 | mdio_gpio_bus_deinit(&pdev->dev); | ||
| 178 | |||
| 179 | return ret; | ||
| 172 | } | 180 | } |
| 173 | 181 | ||
| 174 | static int __devexit mdio_gpio_remove(struct platform_device *pdev) | 182 | static int __devexit mdio_gpio_remove(struct platform_device *pdev) |
| @@ -179,29 +187,12 @@ static int __devexit mdio_gpio_remove(struct platform_device *pdev) | |||
| 179 | } | 187 | } |
| 180 | 188 | ||
| 181 | #ifdef CONFIG_OF_GPIO | 189 | #ifdef CONFIG_OF_GPIO |
| 182 | static void __devinit add_phy(struct mdio_gpio_platform_data *pdata, | ||
| 183 | struct device_node *np) | ||
| 184 | { | ||
| 185 | const u32 *data; | ||
| 186 | int len, id, irq; | ||
| 187 | |||
| 188 | data = of_get_property(np, "reg", &len); | ||
| 189 | if (!data || len != 4) | ||
| 190 | return; | ||
| 191 | |||
| 192 | id = *data; | ||
| 193 | pdata->phy_mask &= ~(1 << id); | ||
| 194 | |||
| 195 | irq = of_irq_to_resource(np, 0, NULL); | ||
| 196 | if (irq) | ||
| 197 | pdata->irqs[id] = irq; | ||
| 198 | } | ||
| 199 | 190 | ||
| 200 | static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, | 191 | static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, |
| 201 | const struct of_device_id *match) | 192 | const struct of_device_id *match) |
| 202 | { | 193 | { |
| 203 | struct device_node *np = NULL; | ||
| 204 | struct mdio_gpio_platform_data *pdata; | 194 | struct mdio_gpio_platform_data *pdata; |
| 195 | struct mii_bus *new_bus; | ||
| 205 | int ret; | 196 | int ret; |
| 206 | 197 | ||
| 207 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 198 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
| @@ -215,14 +206,18 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, | |||
| 215 | 206 | ||
| 216 | ret = of_get_gpio(ofdev->node, 1); | 207 | ret = of_get_gpio(ofdev->node, 1); |
| 217 | if (ret < 0) | 208 | if (ret < 0) |
| 218 | goto out_free; | 209 | goto out_free; |
| 219 | pdata->mdio = ret; | 210 | pdata->mdio = ret; |
| 220 | 211 | ||
| 221 | while ((np = of_get_next_child(ofdev->node, np))) | 212 | new_bus = mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); |
| 222 | if (!strcmp(np->type, "ethernet-phy")) | 213 | if (!new_bus) |
| 223 | add_phy(pdata, np); | 214 | return -ENODEV; |
| 224 | 215 | ||
| 225 | return mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); | 216 | ret = of_mdiobus_register(new_bus, ofdev->node); |
| 217 | if (ret) | ||
| 218 | mdio_gpio_bus_deinit(&ofdev->dev); | ||
| 219 | |||
| 220 | return ret; | ||
| 226 | 221 | ||
| 227 | out_free: | 222 | out_free: |
| 228 | kfree(pdata); | 223 | kfree(pdata); |
