Commit 34c44eb3 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-ibm-emac-modernize-a-bit'

Rosen Penev says:

====================
net: ibm: emac: modernize a bit
====================

Link: https://patch.msgid.link/20240912024903.6201-1-rosenp@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents beb2baa9 39b9b780
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
...@@ -96,11 +95,6 @@ MODULE_LICENSE("GPL"); ...@@ -96,11 +95,6 @@ MODULE_LICENSE("GPL");
static u32 busy_phy_map; static u32 busy_phy_map;
static DEFINE_MUTEX(emac_phy_map_lock); static DEFINE_MUTEX(emac_phy_map_lock);
/* This is the wait queue used to wait on any event related to probe, that
* is discovery of MALs, other EMACs, ZMII/RGMIIs, etc...
*/
static DECLARE_WAIT_QUEUE_HEAD(emac_probe_wait);
/* Having stable interface names is a doomed idea. However, it would be nice /* Having stable interface names is a doomed idea. However, it would be nice
* if we didn't have completely random interface names at boot too :-) It's * if we didn't have completely random interface names at boot too :-) It's
* just a matter of making everybody's life easier. Since we are doing * just a matter of making everybody's life easier. Since we are doing
...@@ -116,9 +110,6 @@ static DECLARE_WAIT_QUEUE_HEAD(emac_probe_wait); ...@@ -116,9 +110,6 @@ static DECLARE_WAIT_QUEUE_HEAD(emac_probe_wait);
#define EMAC_BOOT_LIST_SIZE 4 #define EMAC_BOOT_LIST_SIZE 4
static struct device_node *emac_boot_list[EMAC_BOOT_LIST_SIZE]; static struct device_node *emac_boot_list[EMAC_BOOT_LIST_SIZE];
/* How long should I wait for dependent devices ? */
#define EMAC_PROBE_DEP_TIMEOUT (HZ * 5)
/* I don't want to litter system log with timeout errors /* I don't want to litter system log with timeout errors
* when we have brain-damaged PHY. * when we have brain-damaged PHY.
*/ */
...@@ -973,8 +964,6 @@ static void __emac_set_multicast_list(struct emac_instance *dev) ...@@ -973,8 +964,6 @@ static void __emac_set_multicast_list(struct emac_instance *dev)
* we need is just to stop RX channel. This seems to work on all * we need is just to stop RX channel. This seems to work on all
* tested SoCs. --ebs * tested SoCs. --ebs
* *
* If we need the full reset, we might just trigger the workqueue
* and do it async... a bit nasty but should work --BenH
*/ */
dev->mcast_pending = 0; dev->mcast_pending = 0;
emac_rx_disable(dev); emac_rx_disable(dev);
...@@ -1228,18 +1217,10 @@ static void emac_print_link_status(struct emac_instance *dev) ...@@ -1228,18 +1217,10 @@ static void emac_print_link_status(struct emac_instance *dev)
static int emac_open(struct net_device *ndev) static int emac_open(struct net_device *ndev)
{ {
struct emac_instance *dev = netdev_priv(ndev); struct emac_instance *dev = netdev_priv(ndev);
int err, i; int i;
DBG(dev, "open" NL); DBG(dev, "open" NL);
/* Setup error IRQ handler */
err = request_irq(dev->emac_irq, emac_irq, 0, "EMAC", dev);
if (err) {
printk(KERN_ERR "%s: failed to request IRQ %d\n",
ndev->name, dev->emac_irq);
return err;
}
/* Allocate RX ring */ /* Allocate RX ring */
for (i = 0; i < NUM_RX_BUFF; ++i) for (i = 0; i < NUM_RX_BUFF; ++i)
if (emac_alloc_rx_skb(dev, i)) { if (emac_alloc_rx_skb(dev, i)) {
...@@ -1293,8 +1274,6 @@ static int emac_open(struct net_device *ndev) ...@@ -1293,8 +1274,6 @@ static int emac_open(struct net_device *ndev)
return 0; return 0;
oom: oom:
emac_clean_rx_ring(dev); emac_clean_rx_ring(dev);
free_irq(dev->emac_irq, dev);
return -ENOMEM; return -ENOMEM;
} }
...@@ -1408,8 +1387,6 @@ static int emac_close(struct net_device *ndev) ...@@ -1408,8 +1387,6 @@ static int emac_close(struct net_device *ndev)
emac_clean_tx_ring(dev); emac_clean_tx_ring(dev);
emac_clean_rx_ring(dev); emac_clean_rx_ring(dev);
free_irq(dev->emac_irq, dev);
netif_carrier_off(ndev); netif_carrier_off(ndev);
return 0; return 0;
...@@ -2390,7 +2367,9 @@ static int emac_check_deps(struct emac_instance *dev, ...@@ -2390,7 +2367,9 @@ static int emac_check_deps(struct emac_instance *dev,
if (deps[i].drvdata != NULL) if (deps[i].drvdata != NULL)
there++; there++;
} }
return there == EMAC_DEP_COUNT; if (there != EMAC_DEP_COUNT)
return -EPROBE_DEFER;
return 0;
} }
static void emac_put_deps(struct emac_instance *dev) static void emac_put_deps(struct emac_instance *dev)
...@@ -2402,19 +2381,6 @@ static void emac_put_deps(struct emac_instance *dev) ...@@ -2402,19 +2381,6 @@ static void emac_put_deps(struct emac_instance *dev)
platform_device_put(dev->tah_dev); platform_device_put(dev->tah_dev);
} }
static int emac_of_bus_notify(struct notifier_block *nb, unsigned long action,
void *data)
{
/* We are only intereted in device addition */
if (action == BUS_NOTIFY_BOUND_DRIVER)
wake_up_all(&emac_probe_wait);
return 0;
}
static struct notifier_block emac_of_bus_notifier = {
.notifier_call = emac_of_bus_notify
};
static int emac_wait_deps(struct emac_instance *dev) static int emac_wait_deps(struct emac_instance *dev)
{ {
struct emac_depentry deps[EMAC_DEP_COUNT]; struct emac_depentry deps[EMAC_DEP_COUNT];
...@@ -2431,18 +2397,13 @@ static int emac_wait_deps(struct emac_instance *dev) ...@@ -2431,18 +2397,13 @@ static int emac_wait_deps(struct emac_instance *dev)
deps[EMAC_DEP_MDIO_IDX].phandle = dev->mdio_ph; deps[EMAC_DEP_MDIO_IDX].phandle = dev->mdio_ph;
if (dev->blist && dev->blist > emac_boot_list) if (dev->blist && dev->blist > emac_boot_list)
deps[EMAC_DEP_PREV_IDX].phandle = 0xffffffffu; deps[EMAC_DEP_PREV_IDX].phandle = 0xffffffffu;
bus_register_notifier(&platform_bus_type, &emac_of_bus_notifier); err = emac_check_deps(dev, deps);
wait_event_timeout(emac_probe_wait,
emac_check_deps(dev, deps),
EMAC_PROBE_DEP_TIMEOUT);
bus_unregister_notifier(&platform_bus_type, &emac_of_bus_notifier);
err = emac_check_deps(dev, deps) ? 0 : -ENODEV;
for (i = 0; i < EMAC_DEP_COUNT; i++) { for (i = 0; i < EMAC_DEP_COUNT; i++) {
of_node_put(deps[i].node); of_node_put(deps[i].node);
if (err) if (err)
platform_device_put(deps[i].ofdev); platform_device_put(deps[i].ofdev);
} }
if (err == 0) { if (!err) {
dev->mal_dev = deps[EMAC_DEP_MAL_IDX].ofdev; dev->mal_dev = deps[EMAC_DEP_MAL_IDX].ofdev;
dev->zmii_dev = deps[EMAC_DEP_ZMII_IDX].ofdev; dev->zmii_dev = deps[EMAC_DEP_ZMII_IDX].ofdev;
dev->rgmii_dev = deps[EMAC_DEP_RGMII_IDX].ofdev; dev->rgmii_dev = deps[EMAC_DEP_RGMII_IDX].ofdev;
...@@ -2456,22 +2417,21 @@ static int emac_wait_deps(struct emac_instance *dev) ...@@ -2456,22 +2417,21 @@ static int emac_wait_deps(struct emac_instance *dev)
static int emac_read_uint_prop(struct device_node *np, const char *name, static int emac_read_uint_prop(struct device_node *np, const char *name,
u32 *val, int fatal) u32 *val, int fatal)
{ {
int len; int err;
const u32 *prop = of_get_property(np, name, &len);
if (prop == NULL || len < sizeof(u32)) { err = of_property_read_u32(np, name, val);
if (err) {
if (fatal) if (fatal)
printk(KERN_ERR "%pOF: missing %s property\n", pr_err("%pOF: missing %s property", np, name);
np, name); return err;
return -ENODEV;
} }
*val = *prop;
return 0; return 0;
} }
static void emac_adjust_link(struct net_device *ndev) static void emac_adjust_link(struct net_device *ndev)
{ {
struct emac_instance *dev = netdev_priv(ndev); struct emac_instance *dev = netdev_priv(ndev);
struct phy_device *phy = dev->phy_dev; struct phy_device *phy = ndev->phydev;
dev->phy.autoneg = phy->autoneg; dev->phy.autoneg = phy->autoneg;
dev->phy.speed = phy->speed; dev->phy.speed = phy->speed;
...@@ -2522,22 +2482,20 @@ static int emac_mdio_phy_start_aneg(struct mii_phy *phy, ...@@ -2522,22 +2482,20 @@ static int emac_mdio_phy_start_aneg(struct mii_phy *phy,
static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise) static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
{ {
struct net_device *ndev = phy->dev; struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
phy->autoneg = AUTONEG_ENABLE; phy->autoneg = AUTONEG_ENABLE;
phy->advertising = advertise; phy->advertising = advertise;
return emac_mdio_phy_start_aneg(phy, dev->phy_dev); return emac_mdio_phy_start_aneg(phy, ndev->phydev);
} }
static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd) static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
{ {
struct net_device *ndev = phy->dev; struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
phy->autoneg = AUTONEG_DISABLE; phy->autoneg = AUTONEG_DISABLE;
phy->speed = speed; phy->speed = speed;
phy->duplex = fd; phy->duplex = fd;
return emac_mdio_phy_start_aneg(phy, dev->phy_dev); return emac_mdio_phy_start_aneg(phy, ndev->phydev);
} }
static int emac_mdio_poll_link(struct mii_phy *phy) static int emac_mdio_poll_link(struct mii_phy *phy)
...@@ -2546,20 +2504,19 @@ static int emac_mdio_poll_link(struct mii_phy *phy) ...@@ -2546,20 +2504,19 @@ static int emac_mdio_poll_link(struct mii_phy *phy)
struct emac_instance *dev = netdev_priv(ndev); struct emac_instance *dev = netdev_priv(ndev);
int res; int res;
res = phy_read_status(dev->phy_dev); res = phy_read_status(ndev->phydev);
if (res) { if (res) {
dev_err(&dev->ofdev->dev, "link update failed (%d).", res); dev_err(&dev->ofdev->dev, "link update failed (%d).", res);
return ethtool_op_get_link(ndev); return ethtool_op_get_link(ndev);
} }
return dev->phy_dev->link; return ndev->phydev->link;
} }
static int emac_mdio_read_link(struct mii_phy *phy) static int emac_mdio_read_link(struct mii_phy *phy)
{ {
struct net_device *ndev = phy->dev; struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev); struct phy_device *phy_dev = ndev->phydev;
struct phy_device *phy_dev = dev->phy_dev;
int res; int res;
res = phy_read_status(phy_dev); res = phy_read_status(phy_dev);
...@@ -2576,10 +2533,9 @@ static int emac_mdio_read_link(struct mii_phy *phy) ...@@ -2576,10 +2533,9 @@ static int emac_mdio_read_link(struct mii_phy *phy)
static int emac_mdio_init_phy(struct mii_phy *phy) static int emac_mdio_init_phy(struct mii_phy *phy)
{ {
struct net_device *ndev = phy->dev; struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
phy_start(dev->phy_dev); phy_start(ndev->phydev);
return phy_init_hw(dev->phy_dev); return phy_init_hw(ndev->phydev);
} }
static const struct mii_phy_ops emac_dt_mdio_phy_ops = { static const struct mii_phy_ops emac_dt_mdio_phy_ops = {
...@@ -2593,6 +2549,7 @@ static const struct mii_phy_ops emac_dt_mdio_phy_ops = { ...@@ -2593,6 +2549,7 @@ static const struct mii_phy_ops emac_dt_mdio_phy_ops = {
static int emac_dt_mdio_probe(struct emac_instance *dev) static int emac_dt_mdio_probe(struct emac_instance *dev)
{ {
struct device_node *mii_np; struct device_node *mii_np;
struct mii_bus *bus;
int res; int res;
mii_np = of_get_child_by_name(dev->ofdev->dev.of_node, "mdio"); mii_np = of_get_child_by_name(dev->ofdev->dev.of_node, "mdio");
...@@ -2606,23 +2563,23 @@ static int emac_dt_mdio_probe(struct emac_instance *dev) ...@@ -2606,23 +2563,23 @@ static int emac_dt_mdio_probe(struct emac_instance *dev)
goto put_node; goto put_node;
} }
dev->mii_bus = devm_mdiobus_alloc(&dev->ofdev->dev); bus = devm_mdiobus_alloc(&dev->ofdev->dev);
if (!dev->mii_bus) { if (!bus) {
res = -ENOMEM; res = -ENOMEM;
goto put_node; goto put_node;
} }
dev->mii_bus->priv = dev->ndev; bus->priv = dev->ndev;
dev->mii_bus->parent = dev->ndev->dev.parent; bus->parent = dev->ndev->dev.parent;
dev->mii_bus->name = "emac_mdio"; bus->name = "emac_mdio";
dev->mii_bus->read = &emac_mii_bus_read; bus->read = &emac_mii_bus_read;
dev->mii_bus->write = &emac_mii_bus_write; bus->write = &emac_mii_bus_write;
dev->mii_bus->reset = &emac_mii_bus_reset; bus->reset = &emac_mii_bus_reset;
snprintf(dev->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev->ofdev->name); snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev->ofdev->name);
res = of_mdiobus_register(dev->mii_bus, mii_np); res = devm_of_mdiobus_register(&dev->ofdev->dev, bus, mii_np);
if (res) { if (res) {
dev_err(&dev->ofdev->dev, "cannot register MDIO bus %s (%d)", dev_err(&dev->ofdev->dev, "cannot register MDIO bus %s (%d)",
dev->mii_bus->name, res); bus->name, res);
} }
put_node: put_node:
...@@ -2633,26 +2590,28 @@ static int emac_dt_mdio_probe(struct emac_instance *dev) ...@@ -2633,26 +2590,28 @@ static int emac_dt_mdio_probe(struct emac_instance *dev)
static int emac_dt_phy_connect(struct emac_instance *dev, static int emac_dt_phy_connect(struct emac_instance *dev,
struct device_node *phy_handle) struct device_node *phy_handle)
{ {
struct phy_device *phy_dev;
dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def), dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def),
GFP_KERNEL); GFP_KERNEL);
if (!dev->phy.def) if (!dev->phy.def)
return -ENOMEM; return -ENOMEM;
dev->phy_dev = of_phy_connect(dev->ndev, phy_handle, &emac_adjust_link, phy_dev = of_phy_connect(dev->ndev, phy_handle, &emac_adjust_link, 0,
0, dev->phy_mode); dev->phy_mode);
if (!dev->phy_dev) { if (!phy_dev) {
dev_err(&dev->ofdev->dev, "failed to connect to PHY.\n"); dev_err(&dev->ofdev->dev, "failed to connect to PHY.\n");
return -ENODEV; return -ENODEV;
} }
dev->phy.def->phy_id = dev->phy_dev->drv->phy_id; dev->phy.def->phy_id = phy_dev->drv->phy_id;
dev->phy.def->phy_id_mask = dev->phy_dev->drv->phy_id_mask; dev->phy.def->phy_id_mask = phy_dev->drv->phy_id_mask;
dev->phy.def->name = dev->phy_dev->drv->name; dev->phy.def->name = phy_dev->drv->name;
dev->phy.def->ops = &emac_dt_mdio_phy_ops; dev->phy.def->ops = &emac_dt_mdio_phy_ops;
ethtool_convert_link_mode_to_legacy_u32(&dev->phy.features, ethtool_convert_link_mode_to_legacy_u32(&dev->phy.features,
dev->phy_dev->supported); phy_dev->supported);
dev->phy.address = dev->phy_dev->mdio.addr; dev->phy.address = phy_dev->mdio.addr;
dev->phy.mode = dev->phy_dev->interface; dev->phy.mode = phy_dev->interface;
return 0; return 0;
} }
...@@ -2668,8 +2627,6 @@ static int emac_dt_phy_probe(struct emac_instance *dev) ...@@ -2668,8 +2627,6 @@ static int emac_dt_phy_probe(struct emac_instance *dev)
res = emac_dt_mdio_probe(dev); res = emac_dt_mdio_probe(dev);
if (!res) { if (!res) {
res = emac_dt_phy_connect(dev, phy_handle); res = emac_dt_phy_connect(dev, phy_handle);
if (res)
mdiobus_unregister(dev->mii_bus);
} }
} }
...@@ -2708,13 +2665,11 @@ static int emac_init_phy(struct emac_instance *dev) ...@@ -2708,13 +2665,11 @@ static int emac_init_phy(struct emac_instance *dev)
return res; return res;
res = of_phy_register_fixed_link(np); res = of_phy_register_fixed_link(np);
dev->phy_dev = of_phy_find_device(np); ndev->phydev = of_phy_find_device(np);
if (res || !dev->phy_dev) { if (res || !ndev->phydev)
mdiobus_unregister(dev->mii_bus);
return res ? res : -EINVAL; return res ? res : -EINVAL;
}
emac_adjust_link(dev->ndev); emac_adjust_link(dev->ndev);
put_device(&dev->phy_dev->mdio.dev); put_device(&ndev->phydev->mdio.dev);
} }
return 0; return 0;
} }
...@@ -3053,7 +3008,7 @@ static int emac_probe(struct platform_device *ofdev) ...@@ -3053,7 +3008,7 @@ static int emac_probe(struct platform_device *ofdev)
/* Allocate our net_device structure */ /* Allocate our net_device structure */
err = -ENOMEM; err = -ENOMEM;
ndev = alloc_etherdev(sizeof(struct emac_instance)); ndev = devm_alloc_etherdev(&ofdev->dev, sizeof(struct emac_instance));
if (!ndev) if (!ndev)
goto err_gone; goto err_gone;
...@@ -3072,35 +3027,40 @@ static int emac_probe(struct platform_device *ofdev) ...@@ -3072,35 +3027,40 @@ static int emac_probe(struct platform_device *ofdev)
/* Init various config data based on device-tree */ /* Init various config data based on device-tree */
err = emac_init_config(dev); err = emac_init_config(dev);
if (err) if (err)
goto err_free; goto err_gone;
/* Get interrupts. EMAC irq is mandatory, WOL irq is optional */ /* Get interrupts. EMAC irq is mandatory */
dev->emac_irq = irq_of_parse_and_map(np, 0); dev->emac_irq = irq_of_parse_and_map(np, 0);
dev->wol_irq = irq_of_parse_and_map(np, 1);
if (!dev->emac_irq) { if (!dev->emac_irq) {
printk(KERN_ERR "%pOF: Can't map main interrupt\n", np); printk(KERN_ERR "%pOF: Can't map main interrupt\n", np);
err = -ENODEV; err = -ENODEV;
goto err_free; goto err_gone;
}
/* Setup error IRQ handler */
err = devm_request_irq(&ofdev->dev, dev->emac_irq, emac_irq, 0, "EMAC",
dev);
if (err) {
dev_err_probe(&ofdev->dev, err, "failed to request IRQ %d",
dev->emac_irq);
goto err_gone;
} }
ndev->irq = dev->emac_irq; ndev->irq = dev->emac_irq;
/* Map EMAC regs */ /* Map EMAC regs */
// TODO : platform_get_resource() and devm_ioremap_resource() // TODO : platform_get_resource() and devm_ioremap_resource()
dev->emacp = of_iomap(np, 0); dev->emacp = devm_of_iomap(&ofdev->dev, np, 0, NULL);
if (dev->emacp == NULL) { if (!dev->emacp) {
printk(KERN_ERR "%pOF: Can't map device registers!\n", np); dev_err(&ofdev->dev, "can't map device registers");
err = -ENOMEM; err = -ENOMEM;
goto err_irq_unmap; goto err_gone;
} }
/* Wait for dependent devices */ /* Wait for dependent devices */
err = emac_wait_deps(dev); err = emac_wait_deps(dev);
if (err) { if (err)
printk(KERN_ERR goto err_gone;
"%pOF: Timeout waiting for dependent devices\n", np);
/* display more info about what's missing ? */
goto err_reg_unmap;
}
dev->mal = platform_get_drvdata(dev->mal_dev); dev->mal = platform_get_drvdata(dev->mal_dev);
if (dev->mdio_dev != NULL) if (dev->mdio_dev != NULL)
dev->mdio_instance = platform_get_drvdata(dev->mdio_dev); dev->mdio_instance = platform_get_drvdata(dev->mdio_dev);
...@@ -3187,7 +3147,7 @@ static int emac_probe(struct platform_device *ofdev) ...@@ -3187,7 +3147,7 @@ static int emac_probe(struct platform_device *ofdev)
netif_carrier_off(ndev); netif_carrier_off(ndev);
err = register_netdev(ndev); err = devm_register_netdev(&ofdev->dev, ndev);
if (err) { if (err) {
printk(KERN_ERR "%pOF: failed to register net device (%d)!\n", printk(KERN_ERR "%pOF: failed to register net device (%d)!\n",
np, err); np, err);
...@@ -3200,10 +3160,6 @@ static int emac_probe(struct platform_device *ofdev) ...@@ -3200,10 +3160,6 @@ static int emac_probe(struct platform_device *ofdev)
wmb(); wmb();
platform_set_drvdata(ofdev, dev); platform_set_drvdata(ofdev, dev);
/* There's a new kid in town ! Let's tell everybody */
wake_up_all(&emac_probe_wait);
printk(KERN_INFO "%s: EMAC-%d %pOF, MAC %pM\n", printk(KERN_INFO "%s: EMAC-%d %pOF, MAC %pM\n",
ndev->name, dev->cell_index, np, ndev->dev_addr); ndev->name, dev->cell_index, np, ndev->dev_addr);
...@@ -3232,24 +3188,9 @@ static int emac_probe(struct platform_device *ofdev) ...@@ -3232,24 +3188,9 @@ static int emac_probe(struct platform_device *ofdev)
mal_unregister_commac(dev->mal, &dev->commac); mal_unregister_commac(dev->mal, &dev->commac);
err_rel_deps: err_rel_deps:
emac_put_deps(dev); emac_put_deps(dev);
err_reg_unmap:
iounmap(dev->emacp);
err_irq_unmap:
if (dev->wol_irq)
irq_dispose_mapping(dev->wol_irq);
if (dev->emac_irq)
irq_dispose_mapping(dev->emac_irq);
err_free:
free_netdev(ndev);
err_gone: err_gone:
/* if we were on the bootlist, remove us as we won't show up and if (blist)
* wake up all waiters to notify them in case they were waiting
* on us
*/
if (blist) {
*blist = NULL; *blist = NULL;
wake_up_all(&emac_probe_wait);
}
return err; return err;
} }
...@@ -3259,8 +3200,6 @@ static void emac_remove(struct platform_device *ofdev) ...@@ -3259,8 +3200,6 @@ static void emac_remove(struct platform_device *ofdev)
DBG(dev, "remove" NL); DBG(dev, "remove" NL);
unregister_netdev(dev->ndev);
cancel_work_sync(&dev->reset_work); cancel_work_sync(&dev->reset_work);
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH)) if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
...@@ -3270,26 +3209,11 @@ static void emac_remove(struct platform_device *ofdev) ...@@ -3270,26 +3209,11 @@ static void emac_remove(struct platform_device *ofdev)
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII)) if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
zmii_detach(dev->zmii_dev, dev->zmii_port); zmii_detach(dev->zmii_dev, dev->zmii_port);
if (dev->phy_dev)
phy_disconnect(dev->phy_dev);
if (dev->mii_bus)
mdiobus_unregister(dev->mii_bus);
busy_phy_map &= ~(1 << dev->phy.address); busy_phy_map &= ~(1 << dev->phy.address);
DBG(dev, "busy_phy_map now %#x" NL, busy_phy_map); DBG(dev, "busy_phy_map now %#x" NL, busy_phy_map);
mal_unregister_commac(dev->mal, &dev->commac); mal_unregister_commac(dev->mal, &dev->commac);
emac_put_deps(dev); emac_put_deps(dev);
iounmap(dev->emacp);
if (dev->wol_irq)
irq_dispose_mapping(dev->wol_irq);
if (dev->emac_irq)
irq_dispose_mapping(dev->emac_irq);
free_netdev(dev->ndev);
} }
/* XXX Features in here should be replaced by properties... */ /* XXX Features in here should be replaced by properties... */
...@@ -3328,16 +3252,15 @@ static void __init emac_make_bootlist(void) ...@@ -3328,16 +3252,15 @@ static void __init emac_make_bootlist(void)
/* Collect EMACs */ /* Collect EMACs */
while((np = of_find_all_nodes(np)) != NULL) { while((np = of_find_all_nodes(np)) != NULL) {
const u32 *idx; u32 idx;
if (of_match_node(emac_match, np) == NULL) if (of_match_node(emac_match, np) == NULL)
continue; continue;
if (of_property_read_bool(np, "unused")) if (of_property_read_bool(np, "unused"))
continue; continue;
idx = of_get_property(np, "cell-index", NULL); if (of_property_read_u32(np, "cell-index", &idx))
if (idx == NULL)
continue; continue;
cell_indices[i] = *idx; cell_indices[i] = idx;
emac_boot_list[i++] = of_node_get(np); emac_boot_list[i++] = of_node_get(np);
if (i >= EMAC_BOOT_LIST_SIZE) { if (i >= EMAC_BOOT_LIST_SIZE) {
of_node_put(np); of_node_put(np);
......
...@@ -188,10 +188,6 @@ struct emac_instance { ...@@ -188,10 +188,6 @@ struct emac_instance {
struct emac_instance *mdio_instance; struct emac_instance *mdio_instance;
struct mutex mdio_lock; struct mutex mdio_lock;
/* Device-tree based phy configuration */
struct mii_bus *mii_bus;
struct phy_device *phy_dev;
/* ZMII infos if any */ /* ZMII infos if any */
u32 zmii_ph; u32 zmii_ph;
u32 zmii_port; u32 zmii_port;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment