Commit 00a284c3 authored by Kumar Gala's avatar Kumar Gala Committed by Linus Torvalds

[PATCH] ppc32: Convert gianfar ethernet driver from using an OCP to platform_device

Convert gianfar ethernet driver from using an OCP to platform_device.
Signed-off-by: default avatarKumar Gala <kumar.gala@freescale.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ddacbaac
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* controllers on the Freescale 8540/8560 integrated processors, * controllers on the Freescale 8540/8560 integrated processors,
* as well as the Fast Ethernet Controller on the 8540. * as well as the Fast Ethernet Controller on the 8540.
* *
* The driver is initialized through OCP. Structures which * The driver is initialized through platform_device. Structures which
* define the configuration needed by the board are defined in a * define the configuration needed by the board are defined in a
* board structure in arch/ppc/platforms (though I do not * board structure in arch/ppc/platforms (though I do not
* discount the possibility that other architectures could one * discount the possibility that other architectures could one
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/device.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -130,8 +131,8 @@ static void gfar_phy_timer(unsigned long data); ...@@ -130,8 +131,8 @@ static void gfar_phy_timer(unsigned long data);
static void adjust_link(struct net_device *dev); static void adjust_link(struct net_device *dev);
static void init_registers(struct net_device *dev); static void init_registers(struct net_device *dev);
static int init_phy(struct net_device *dev); static int init_phy(struct net_device *dev);
static int gfar_probe(struct ocp_device *ocpdev); static int gfar_probe(struct device *device);
static void gfar_remove(struct ocp_device *ocpdev); static int gfar_remove(struct device *device);
void free_skb_resources(struct gfar_private *priv); void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev); static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
...@@ -148,45 +149,27 @@ MODULE_AUTHOR("Freescale Semiconductor, Inc"); ...@@ -148,45 +149,27 @@ MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION("Gianfar Ethernet Driver"); MODULE_DESCRIPTION("Gianfar Ethernet Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* Called by the ocp code to initialize device data structures static int gfar_probe(struct device *device)
* required for bringing up the device
* returns 0 on success */
static int gfar_probe(struct ocp_device *ocpdev)
{ {
u32 tempval; u32 tempval;
struct ocp_device *mdiodev;
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct gfar_private *priv = NULL; struct gfar_private *priv = NULL;
struct ocp_gfar_data *einfo; struct platform_device *pdev = to_platform_device(device);
struct gianfar_platform_data *einfo;
struct resource *r;
int idx; int idx;
int err = 0; int err = 0;
int dev_ethtool_ops = 0; int dev_ethtool_ops = 0;
einfo = (struct ocp_gfar_data *) ocpdev->def->additions; einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
if (einfo == NULL) { if (einfo == NULL) {
printk(KERN_ERR "gfar %d: Missing additional data!\n", printk(KERN_ERR "gfar %d: Missing additional data!\n",
ocpdev->def->index); pdev->id);
return -ENODEV; return -ENODEV;
} }
/* get a pointer to the register memory which can
* configure the PHYs. If it's different from this set,
* get the device which has those regs */
if ((einfo->phyregidx >= 0) &&
(einfo->phyregidx != ocpdev->def->index)) {
mdiodev = ocp_find_device(OCP_ANY_ID,
OCP_FUNC_GFAR, einfo->phyregidx);
/* If the device which holds the MDIO regs isn't
* up, wait for it to come up */
if (mdiodev == NULL)
return -EAGAIN;
} else {
mdiodev = ocpdev;
}
/* Create an ethernet device instance */ /* Create an ethernet device instance */
dev = alloc_etherdev(sizeof (*priv)); dev = alloc_etherdev(sizeof (*priv));
...@@ -198,9 +181,19 @@ static int gfar_probe(struct ocp_device *ocpdev) ...@@ -198,9 +181,19 @@ static int gfar_probe(struct ocp_device *ocpdev)
/* Set the info in the priv to the current info */ /* Set the info in the priv to the current info */
priv->einfo = einfo; priv->einfo = einfo;
/* fill out IRQ fields */
if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
priv->interruptTransmit = platform_get_irq_byname(pdev, "tx");
priv->interruptReceive = platform_get_irq_byname(pdev, "rx");
priv->interruptError = platform_get_irq_byname(pdev, "error");
} else {
priv->interruptTransmit = platform_get_irq(pdev, 0);
}
/* get a pointer to the register memory */ /* get a pointer to the register memory */
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->regs = (struct gfar *) priv->regs = (struct gfar *)
ioremap(ocpdev->def->paddr, sizeof (struct gfar)); ioremap(r->start, sizeof (struct gfar));
if (priv->regs == NULL) { if (priv->regs == NULL) {
err = -ENOMEM; err = -ENOMEM;
...@@ -209,7 +202,7 @@ static int gfar_probe(struct ocp_device *ocpdev) ...@@ -209,7 +202,7 @@ static int gfar_probe(struct ocp_device *ocpdev)
/* Set the PHY base address */ /* Set the PHY base address */
priv->phyregs = (struct gfar *) priv->phyregs = (struct gfar *)
ioremap(mdiodev->def->paddr, sizeof (struct gfar)); ioremap(einfo->phy_reg_addr, sizeof (struct gfar));
if (priv->phyregs == NULL) { if (priv->phyregs == NULL) {
err = -ENOMEM; err = -ENOMEM;
...@@ -218,7 +211,7 @@ static int gfar_probe(struct ocp_device *ocpdev) ...@@ -218,7 +211,7 @@ static int gfar_probe(struct ocp_device *ocpdev)
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
ocp_set_drvdata(ocpdev, dev); dev_set_drvdata(device, dev);
/* Stop the DMA engine now, in case it was running before */ /* Stop the DMA engine now, in case it was running before */
/* (The firmware could have used it, and left it running). */ /* (The firmware could have used it, and left it running). */
...@@ -255,7 +248,7 @@ static int gfar_probe(struct ocp_device *ocpdev) ...@@ -255,7 +248,7 @@ static int gfar_probe(struct ocp_device *ocpdev)
dev->base_addr = (unsigned long) (priv->regs); dev->base_addr = (unsigned long) (priv->regs);
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &ocpdev->dev); SET_NETDEV_DEV(dev, device);
/* Fill in the dev structure */ /* Fill in the dev structure */
dev->open = gfar_enet_open; dev->open = gfar_enet_open;
...@@ -274,10 +267,10 @@ static int gfar_probe(struct ocp_device *ocpdev) ...@@ -274,10 +267,10 @@ static int gfar_probe(struct ocp_device *ocpdev)
/* Index into the array of possible ethtool /* Index into the array of possible ethtool
* ops to catch all 4 possibilities */ * ops to catch all 4 possibilities */
if((priv->einfo->flags & GFAR_HAS_RMON) == 0) if((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) == 0)
dev_ethtool_ops += 1; dev_ethtool_ops += 1;
if((priv->einfo->flags & GFAR_HAS_COALESCE) == 0) if((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE) == 0)
dev_ethtool_ops += 2; dev_ethtool_ops += 2;
dev->ethtool_ops = gfar_op_array[dev_ethtool_ops]; dev->ethtool_ops = gfar_op_array[dev_ethtool_ops];
...@@ -332,18 +325,21 @@ static int gfar_probe(struct ocp_device *ocpdev) ...@@ -332,18 +325,21 @@ static int gfar_probe(struct ocp_device *ocpdev)
return -ENOMEM; return -ENOMEM;
} }
static void gfar_remove(struct ocp_device *ocpdev) static int gfar_remove(struct device *device)
{ {
struct net_device *dev = ocp_get_drvdata(ocpdev); struct net_device *dev = dev_get_drvdata(device);
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
ocp_set_drvdata(ocpdev, NULL); dev_set_drvdata(device, NULL);
iounmap((void *) priv->regs); iounmap((void *) priv->regs);
iounmap((void *) priv->phyregs); iounmap((void *) priv->phyregs);
free_netdev(dev); free_netdev(dev);
return 0;
} }
/* Configure the PHY for dev. /* Configure the PHY for dev.
* returns 0 if success. -1 if failure * returns 0 if success. -1 if failure
*/ */
...@@ -470,7 +466,7 @@ static void init_registers(struct net_device *dev) ...@@ -470,7 +466,7 @@ static void init_registers(struct net_device *dev)
gfar_write(&priv->regs->rctrl, 0x00000000); gfar_write(&priv->regs->rctrl, 0x00000000);
/* Zero out the rmon mib registers if it has them */ /* Zero out the rmon mib registers if it has them */
if (priv->einfo->flags & GFAR_HAS_RMON) { if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
memset((void *) &(priv->regs->rmon), 0, memset((void *) &(priv->regs->rmon), 0,
sizeof (struct rmon_mib)); sizeof (struct rmon_mib));
...@@ -536,7 +532,7 @@ void stop_gfar(struct net_device *dev) ...@@ -536,7 +532,7 @@ void stop_gfar(struct net_device *dev)
tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
gfar_write(&regs->maccfg1, tempval); gfar_write(&regs->maccfg1, tempval);
if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
/* Clear any pending interrupts */ /* Clear any pending interrupts */
mii_clear_phy_interrupt(priv->mii_info); mii_clear_phy_interrupt(priv->mii_info);
...@@ -548,15 +544,15 @@ void stop_gfar(struct net_device *dev) ...@@ -548,15 +544,15 @@ void stop_gfar(struct net_device *dev)
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
/* Free the IRQs */ /* Free the IRQs */
if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) { if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
free_irq(priv->einfo->interruptError, dev); free_irq(priv->interruptError, dev);
free_irq(priv->einfo->interruptTransmit, dev); free_irq(priv->interruptTransmit, dev);
free_irq(priv->einfo->interruptReceive, dev); free_irq(priv->interruptReceive, dev);
} else { } else {
free_irq(priv->einfo->interruptTransmit, dev); free_irq(priv->interruptTransmit, dev);
} }
if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
free_irq(priv->einfo->interruptPHY, dev); free_irq(priv->einfo->interruptPHY, dev);
} else { } else {
del_timer_sync(&priv->phy_info_timer); del_timer_sync(&priv->phy_info_timer);
...@@ -727,41 +723,41 @@ int startup_gfar(struct net_device *dev) ...@@ -727,41 +723,41 @@ int startup_gfar(struct net_device *dev)
/* If the device has multiple interrupts, register for /* If the device has multiple interrupts, register for
* them. Otherwise, only register for the one */ * them. Otherwise, only register for the one */
if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) { if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
/* Install our interrupt handlers for Error, /* Install our interrupt handlers for Error,
* Transmit, and Receive */ * Transmit, and Receive */
if (request_irq(priv->einfo->interruptError, gfar_error, if (request_irq(priv->interruptError, gfar_error,
0, "enet_error", dev) < 0) { 0, "enet_error", dev) < 0) {
printk(KERN_ERR "%s: Can't get IRQ %d\n", printk(KERN_ERR "%s: Can't get IRQ %d\n",
dev->name, priv->einfo->interruptError); dev->name, priv->interruptError);
err = -1; err = -1;
goto err_irq_fail; goto err_irq_fail;
} }
if (request_irq(priv->einfo->interruptTransmit, gfar_transmit, if (request_irq(priv->interruptTransmit, gfar_transmit,
0, "enet_tx", dev) < 0) { 0, "enet_tx", dev) < 0) {
printk(KERN_ERR "%s: Can't get IRQ %d\n", printk(KERN_ERR "%s: Can't get IRQ %d\n",
dev->name, priv->einfo->interruptTransmit); dev->name, priv->interruptTransmit);
err = -1; err = -1;
goto tx_irq_fail; goto tx_irq_fail;
} }
if (request_irq(priv->einfo->interruptReceive, gfar_receive, if (request_irq(priv->interruptReceive, gfar_receive,
0, "enet_rx", dev) < 0) { 0, "enet_rx", dev) < 0) {
printk(KERN_ERR "%s: Can't get IRQ %d (receive0)\n", printk(KERN_ERR "%s: Can't get IRQ %d (receive0)\n",
dev->name, priv->einfo->interruptReceive); dev->name, priv->interruptReceive);
err = -1; err = -1;
goto rx_irq_fail; goto rx_irq_fail;
} }
} else { } else {
if (request_irq(priv->einfo->interruptTransmit, gfar_interrupt, if (request_irq(priv->interruptTransmit, gfar_interrupt,
0, "gfar_interrupt", dev) < 0) { 0, "gfar_interrupt", dev) < 0) {
printk(KERN_ERR "%s: Can't get IRQ %d\n", printk(KERN_ERR "%s: Can't get IRQ %d\n",
dev->name, priv->einfo->interruptError); dev->name, priv->interruptError);
err = -1; err = -1;
goto err_irq_fail; goto err_irq_fail;
...@@ -815,9 +811,9 @@ int startup_gfar(struct net_device *dev) ...@@ -815,9 +811,9 @@ int startup_gfar(struct net_device *dev)
return 0; return 0;
rx_irq_fail: rx_irq_fail:
free_irq(priv->einfo->interruptTransmit, dev); free_irq(priv->interruptTransmit, dev);
tx_irq_fail: tx_irq_fail:
free_irq(priv->einfo->interruptError, dev); free_irq(priv->interruptError, dev);
err_irq_fail: err_irq_fail:
rx_skb_fail: rx_skb_fail:
free_skb_resources(priv); free_skb_resources(priv);
...@@ -1490,7 +1486,7 @@ static void gfar_phy_change(void *data) ...@@ -1490,7 +1486,7 @@ static void gfar_phy_change(void *data)
adjust_link(dev); adjust_link(dev);
/* Reenable interrupts, if needed */ /* Reenable interrupts, if needed */
if (priv->einfo->flags & GFAR_HAS_PHY_INTR) if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR)
mii_configure_phy_interrupt(priv->mii_info, mii_configure_phy_interrupt(priv->mii_info,
MII_INTERRUPT_ENABLED); MII_INTERRUPT_ENABLED);
} }
...@@ -1547,7 +1543,7 @@ static void gfar_phy_startup_timer(unsigned long data) ...@@ -1547,7 +1543,7 @@ static void gfar_phy_startup_timer(unsigned long data)
del_timer_sync(&priv->phy_info_timer); del_timer_sync(&priv->phy_info_timer);
/* Grab the PHY interrupt, if necessary/possible */ /* Grab the PHY interrupt, if necessary/possible */
if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
if (request_irq(priv->einfo->interruptPHY, if (request_irq(priv->einfo->interruptPHY,
phy_interrupt, phy_interrupt,
SA_SHIRQ, SA_SHIRQ,
...@@ -1758,7 +1754,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1758,7 +1754,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
/* Hmm... */ /* Hmm... */
#if defined (BRIEF_GFAR_ERRORS) || defined (VERBOSE_GFAR_ERRORS) #if defined (BRIEF_GFAR_ERRORS) || defined (VERBOSE_GFAR_ERRORS)
printk(KERN_DEBUG "%s: error interrupt (ievent=0x%08x imask=0x%08x)\n", printk(KERN_DEBUG "%s: error interrupt (ievent=0x%08x imask=0x%08x)\n",
dev->name, events, gfar_read(priv->regs->imask)); dev->name, events, gfar_read(&priv->regs->imask));
#endif #endif
/* Update the error counters */ /* Update the error counters */
...@@ -1829,36 +1825,23 @@ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1829,36 +1825,23 @@ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
} }
/* Structure for a device driver */ /* Structure for a device driver */
static struct ocp_device_id gfar_ids[] = { static struct device_driver gfar_driver = {
{.vendor = OCP_ANY_ID,.function = OCP_FUNC_GFAR}, .name = "fsl-gianfar",
{.vendor = OCP_VENDOR_INVALID} .bus = &platform_bus_type,
};
static struct ocp_driver gfar_driver = {
.name = "gianfar",
.id_table = gfar_ids,
.probe = gfar_probe, .probe = gfar_probe,
.remove = gfar_remove, .remove = gfar_remove,
}; };
static int __init gfar_init(void) static int __init gfar_init(void)
{ {
int rc; return driver_register(&gfar_driver);
rc = ocp_register_driver(&gfar_driver);
if (rc != 0) {
ocp_unregister_driver(&gfar_driver);
return -ENODEV;
}
return 0;
} }
static void __exit gfar_exit(void) static void __exit gfar_exit(void)
{ {
ocp_unregister_driver(&gfar_driver); driver_unregister(&gfar_driver);
} }
module_init(gfar_init); module_init(gfar_init);
module_exit(gfar_exit); module_exit(gfar_exit);
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/fsl_devices.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -47,7 +48,6 @@ ...@@ -47,7 +48,6 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <asm/ocp.h>
#include "gianfar_phy.h" #include "gianfar_phy.h"
/* The maximum number of packets to be handled in one call of gfar_poll */ /* The maximum number of packets to be handled in one call of gfar_poll */
...@@ -510,7 +510,10 @@ struct gfar_private { ...@@ -510,7 +510,10 @@ struct gfar_private {
unsigned int rxclean; unsigned int rxclean;
/* Info structure initialized by board setup code */ /* Info structure initialized by board setup code */
struct ocp_gfar_data *einfo; unsigned int interruptTransmit;
unsigned int interruptReceive;
unsigned int interruptError;
struct gianfar_platform_data *einfo;
struct gfar_mii_info *mii_info; struct gfar_mii_info *mii_info;
int oldspeed; int oldspeed;
......
...@@ -186,9 +186,11 @@ int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -186,9 +186,11 @@ int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
uint gigabit_support = uint gigabit_support =
priv->einfo->flags & GFAR_HAS_GIGABIT ? SUPPORTED_1000baseT_Full : 0; priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
SUPPORTED_1000baseT_Full : 0;
uint gigabit_advert = uint gigabit_advert =
priv->einfo->flags & GFAR_HAS_GIGABIT ? ADVERTISED_1000baseT_Full: 0; priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
ADVERTISED_1000baseT_Full: 0;
cmd->supported = (SUPPORTED_10baseT_Half cmd->supported = (SUPPORTED_10baseT_Half
| SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Half
......
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