#include "stmmac.h"
#define STMMAC_RESOURCE_NAME "stmmaceth"
-#define PHY_RESOURCE_NAME "stmmacphy"
#undef STMMAC_DEBUG
/*#define STMMAC_DEBUG*/
priv->speed = 0;
priv->oldduplex = -1;
- if (priv->phy_addr == -1) {
- /* We don't have a PHY, so do nothing */
- return 0;
- }
-
snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
- priv->phy_addr);
+ priv->plat->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
- priv->phy_interface);
+ priv->plat->interface);
if (IS_ERR(phydev)) {
pr_err("%s: Could not attach to PHY\n", dev->name);
return -ENODEV;
}
pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)"
- " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
+ " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
priv->phydev = phydev;
return 0;
}
-static int stmmacphy_dvr_probe(struct platform_device *pdev)
-{
- struct plat_stmmacphy_data *plat_dat = pdev->dev.platform_data;
-
- pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n",
- plat_dat->bus_id);
-
- return 0;
-}
-
-static int stmmacphy_dvr_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
-static struct platform_driver stmmacphy_driver = {
- .driver = {
- .name = PHY_RESOURCE_NAME,
- },
- .probe = stmmacphy_dvr_probe,
- .remove = stmmacphy_dvr_remove,
-};
-
-/**
- * stmmac_associate_phy
- * @dev: pointer to device structure
- * @data: points to the private structure.
- * Description: Scans through all the PHYs we have registered and checks if
- * any are associated with our MAC. If so, then just fill in
- * the blanks in our local context structure
- */
-static int stmmac_associate_phy(struct device *dev, void *data)
-{
- struct stmmac_priv *priv = (struct stmmac_priv *)data;
- struct plat_stmmacphy_data *plat_dat = dev->platform_data;
-
- DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__,
- plat_dat->bus_id);
-
- /* Check that this phy is for the MAC being initialised */
- if (priv->plat->bus_id != plat_dat->bus_id)
- return 0;
-
- /* OK, this PHY is connected to the MAC.
- Go ahead and get the parameters */
- DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__);
- priv->phy_irq =
- platform_get_irq_byname(to_platform_device(dev), "phyirq");
- DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__,
- plat_dat->bus_id, priv->phy_irq);
-
- /* Override with kernel parameters if supplied XXX CRS XXX
- * this needs to have multiple instances */
- if ((phyaddr >= 0) && (phyaddr <= 31))
- plat_dat->phy_addr = phyaddr;
-
- priv->phy_addr = plat_dat->phy_addr;
- priv->phy_mask = plat_dat->phy_mask;
- priv->phy_interface = plat_dat->interface;
- priv->phy_reset = plat_dat->phy_reset;
-
- DBG(probe, DEBUG, "%s: exiting\n", __func__);
- return 1; /* forces exit of driver_for_each_device() */
-}
-
/**
* stmmac_dvr_probe
* @pdev: platform device pointer
if (ret < 0)
goto out_plat_exit;
- /* associate a PHY - it is provided by another platform bus */
- if (!driver_for_each_device
- (&(stmmacphy_driver.driver), NULL, (void *)priv,
- stmmac_associate_phy)) {
- pr_err("No PHY device is associated with this MAC!\n");
- ret = -ENODEV;
- goto out_unregister;
- }
+ /* Override with kernel parameters if supplied XXX CRS XXX
+ * this needs to have multiple instances */
+ if ((phyaddr >= 0) && (phyaddr <= 31))
+ priv->plat->phy_addr = phyaddr;
pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
"\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
{
int ret;
- if (platform_driver_register(&stmmacphy_driver)) {
- pr_err("No PHY devices registered!\n");
- return -ENODEV;
- }
-
ret = platform_driver_register(&stmmac_driver);
return ret;
}
*/
static void __exit stmmac_cleanup_module(void)
{
- platform_driver_unregister(&stmmacphy_driver);
platform_driver_unregister(&stmmac_driver);
}
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned int mii_address = priv->hw->mii.addr;
- if (priv->phy_reset) {
+ if (priv->plat->mdio_bus_data->phy_reset) {
pr_debug("stmmac_mdio_reset: calling phy_reset\n");
- priv->phy_reset(priv->plat->bsp_priv);
+ priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv);
}
/* This is a workaround for problems with the STE101P PHY.
struct mii_bus *new_bus;
int *irqlist;
struct stmmac_priv *priv = netdev_priv(ndev);
+ struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
int addr, found;
+ if (!mdio_bus_data)
+ return 0;
+
new_bus = mdiobus_alloc();
if (new_bus == NULL)
return -ENOMEM;
- irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
- if (irqlist == NULL) {
- err = -ENOMEM;
- goto irqlist_alloc_fail;
- }
-
- /* Assign IRQ to phy at address phy_addr */
- if (priv->phy_addr != -1)
- irqlist[priv->phy_addr] = priv->phy_irq;
+ if (mdio_bus_data->irqs)
+ irqlist = mdio_bus_data->irqs;
+ else
+ irqlist = priv->mii_irq;
new_bus->name = "STMMAC MII Bus";
new_bus->read = &stmmac_mdio_read;
new_bus->write = &stmmac_mdio_write;
new_bus->reset = &stmmac_mdio_reset;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
+ snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id);
new_bus->priv = ndev;
new_bus->irq = irqlist;
- new_bus->phy_mask = priv->phy_mask;
+ new_bus->phy_mask = mdio_bus_data->phy_mask;
new_bus->parent = priv->device;
err = mdiobus_register(new_bus);
if (err != 0) {
priv->mii = new_bus;
found = 0;
- for (addr = 0; addr < 32; addr++) {
+ for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
struct phy_device *phydev = new_bus->phy_map[addr];
if (phydev) {
- if (priv->phy_addr == -1) {
- priv->phy_addr = addr;
- phydev->irq = priv->phy_irq;
- irqlist[addr] = priv->phy_irq;
+ int act = 0;
+ char irq_num[4];
+ char *irq_str;
+
+ /*
+ * If an IRQ was provided to be assigned after
+ * the bus probe, do it here.
+ */
+ if ((mdio_bus_data->irqs == NULL) &&
+ (mdio_bus_data->probed_phy_irq > 0)) {
+ irqlist[addr] = mdio_bus_data->probed_phy_irq;
+ phydev->irq = mdio_bus_data->probed_phy_irq;
}
- pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n",
- ndev->name, phydev->phy_id, addr,
- phydev->irq, dev_name(&phydev->dev),
- (addr == priv->phy_addr) ? " active" : "");
+
+ /*
+ * If we're going to bind the MAC to this PHY bus,
+ * and no PHY number was provided to the MAC,
+ * use the one probed here.
+ */
+ if ((priv->plat->bus_id == mdio_bus_data->bus_id) &&
+ (priv->plat->phy_addr == -1))
+ priv->plat->phy_addr = addr;
+
+ act = (priv->plat->bus_id == mdio_bus_data->bus_id) &&
+ (priv->plat->phy_addr == addr);
+ switch (phydev->irq) {
+ case PHY_POLL:
+ irq_str = "POLL";
+ break;
+ case PHY_IGNORE_INTERRUPT:
+ irq_str = "IGNORE";
+ break;
+ default:
+ sprintf(irq_num, "%d", phydev->irq);
+ irq_str = irq_num;
+ break;
+ }
+ pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n",
+ ndev->name, phydev->phy_id, addr,
+ irq_str, dev_name(&phydev->dev),
+ act ? " active" : "");
found = 1;
}
}
pr_warning("%s: No PHY found\n", ndev->name);
return 0;
+
bus_register_fail:
- kfree(irqlist);
-irqlist_alloc_fail:
- kfree(new_bus);
+ mdiobus_free(new_bus);
return err;
}
mdiobus_unregister(priv->mii);
priv->mii->priv = NULL;
- kfree(priv->mii);
+ mdiobus_free(priv->mii);
+ priv->mii = NULL;
return 0;
}