summaryrefslogtreecommitdiffstats
path: root/drivers/net/sunlance.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sunlance.c')
-rw-r--r--drivers/net/sunlance.c180
1 files changed, 68 insertions, 112 deletions
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 4e994f8..704301a 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -91,6 +91,9 @@ static char lancestr[] = "LANCE";
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -98,7 +101,6 @@ static char lancestr[] = "LANCE";
#include <asm/pgtable.h>
#include <asm/byteorder.h> /* Used by the checksum routines */
#include <asm/idprom.h>
-#include <asm/sbus.h>
#include <asm/prom.h>
#include <asm/auxio.h> /* For tpe-link-test? setting */
#include <asm/irq.h>
@@ -248,7 +250,7 @@ struct lance_private {
int rx_new, tx_new;
int rx_old, tx_old;
- struct sbus_dma *ledma; /* If set this points to ledma */
+ struct of_device *ledma; /* If set this points to ledma */
char tpe; /* cable-selection is TPE */
char auto_select; /* cable-selection by carrier */
char burst_sizes; /* ledma SBus burst sizes */
@@ -263,7 +265,8 @@ struct lance_private {
char *name;
dma_addr_t init_block_dvma;
struct net_device *dev; /* Backpointer */
- struct sbus_dev *sdev;
+ struct of_device *op;
+ struct of_device *lebuffer;
struct timer_list multicast_timer;
};
@@ -1272,27 +1275,29 @@ static void lance_set_multicast_retry(unsigned long _opaque)
static void lance_free_hwresources(struct lance_private *lp)
{
if (lp->lregs)
- sbus_iounmap(lp->lregs, LANCE_REG_SIZE);
+ of_iounmap(&lp->op->resource[0], lp->lregs, LANCE_REG_SIZE);
+ if (lp->dregs) {
+ struct of_device *ledma = lp->ledma;
+
+ of_iounmap(&ledma->resource[0], lp->dregs,
+ resource_size(&ledma->resource[0]));
+ }
if (lp->init_block_iomem) {
- sbus_iounmap(lp->init_block_iomem,
- sizeof(struct lance_init_block));
+ of_iounmap(&lp->lebuffer->resource[0], lp->init_block_iomem,
+ sizeof(struct lance_init_block));
} else if (lp->init_block_mem) {
- sbus_free_consistent(lp->sdev,
- sizeof(struct lance_init_block),
- lp->init_block_mem,
- lp->init_block_dvma);
+ dma_free_coherent(&lp->op->dev,
+ sizeof(struct lance_init_block),
+ lp->init_block_mem,
+ lp->init_block_dvma);
}
}
/* Ethtool support... */
static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct lance_private *lp = netdev_priv(dev);
-
strcpy(info->driver, "sunlance");
strcpy(info->version, "2.02");
- sprintf(info->bus_info, "SBUS:%d",
- lp->sdev->slot);
}
static u32 sparc_lance_get_link(struct net_device *dev)
@@ -1308,16 +1313,16 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = {
.get_link = sparc_lance_get_link,
};
-static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
- struct sbus_dma *ledma,
- struct sbus_dev *lebuffer)
+static int __devinit sparc_lance_probe_one(struct of_device *op,
+ struct of_device *ledma,
+ struct of_device *lebuffer)
{
+ struct device_node *dp = op->node;
static unsigned version_printed;
- struct device_node *dp = sdev->ofdev.node;
- struct net_device *dev;
struct lance_private *lp;
- int i;
+ struct net_device *dev;
DECLARE_MAC_BUF(mac);
+ int i;
dev = alloc_etherdev(sizeof(struct lance_private) + 8);
if (!dev)
@@ -1338,14 +1343,27 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
dev->dev_addr[i] = idprom->id_ethaddr[i];
/* Get the IO region */
- lp->lregs = sbus_ioremap(&sdev->resource[0], 0,
- LANCE_REG_SIZE, lancestr);
+ lp->lregs = of_ioremap(&op->resource[0], 0,
+ LANCE_REG_SIZE, lancestr);
if (!lp->lregs) {
printk(KERN_ERR "SunLance: Cannot map registers.\n");
goto fail;
}
- lp->sdev = sdev;
+ lp->ledma = ledma;
+ if (lp->ledma) {
+ lp->dregs = of_ioremap(&ledma->resource[0], 0,
+ resource_size(&ledma->resource[0]),
+ "ledma");
+ if (!lp->dregs) {
+ printk(KERN_ERR "SunLance: Cannot map "
+ "ledma registers.\n");
+ goto fail;
+ }
+ }
+
+ lp->op = op;
+ lp->lebuffer = lebuffer;
if (lebuffer) {
/* sanity check */
if (lebuffer->resource[0].start & 7) {
@@ -1353,8 +1371,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
goto fail;
}
lp->init_block_iomem =
- sbus_ioremap(&lebuffer->resource[0], 0,
- sizeof(struct lance_init_block), "lebuffer");
+ of_ioremap(&lebuffer->resource[0], 0,
+ sizeof(struct lance_init_block), "lebuffer");
if (!lp->init_block_iomem) {
printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
goto fail;
@@ -1366,9 +1384,10 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
lp->tx = lance_tx_pio;
} else {
lp->init_block_mem =
- sbus_alloc_consistent(sdev, sizeof(struct lance_init_block),
- &lp->init_block_dvma);
- if (!lp->init_block_mem || lp->init_block_dvma == 0) {
+ dma_alloc_coherent(&op->dev,
+ sizeof(struct lance_init_block),
+ &lp->init_block_dvma, GFP_ATOMIC);
+ if (!lp->init_block_mem) {
printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n");
goto fail;
}
@@ -1383,13 +1402,13 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
LE_C3_BCON));
lp->name = lancestr;
- lp->ledma = ledma;
lp->burst_sizes = 0;
if (lp->ledma) {
- struct device_node *ledma_dp = ledma->sdev->ofdev.node;
- const char *prop;
+ struct device_node *ledma_dp = ledma->node;
+ struct device_node *sbus_dp;
unsigned int sbmask;
+ const char *prop;
u32 csr;
/* Find burst-size property for ledma */
@@ -1397,7 +1416,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
"burst-sizes", 0);
/* ledma may be capable of fast bursts, but sbus may not. */
- sbmask = of_getintprop_default(ledma_dp, "burst-sizes",
+ sbus_dp = ledma_dp->parent;
+ sbmask = of_getintprop_default(sbus_dp, "burst-sizes",
DMA_BURSTBITS);
lp->burst_sizes &= sbmask;
@@ -1435,8 +1455,6 @@ no_link_test:
lp->tpe = 1;
}
- lp->dregs = ledma->regs;
-
/* Reset ledma */
csr = sbus_readl(lp->dregs + DMA_CSR);
sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR);
@@ -1446,7 +1464,7 @@ no_link_test:
lp->dregs = NULL;
lp->dev = dev;
- SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
+ SET_NETDEV_DEV(dev, &op->dev);
dev->open = &lance_open;
dev->stop = &lance_close;
dev->hard_start_xmit = &lance_start_xmit;
@@ -1455,9 +1473,7 @@ no_link_test:
dev->set_multicast_list = &lance_set_multicast;
dev->ethtool_ops = &sparc_lance_ethtool_ops;
- dev->irq = sdev->irqs[0];
-
- dev->dma = 0;
+ dev->irq = op->irqs[0];
/* We cannot sleep if the chip is busy during a
* multicast list update event, because such events
@@ -1473,7 +1489,7 @@ no_link_test:
goto fail;
}
- dev_set_drvdata(&sdev->ofdev.dev, lp);
+ dev_set_drvdata(&op->dev, lp);
printk(KERN_INFO "%s: LANCE %s\n",
dev->name, print_mac(mac, dev->dev_addr));
@@ -1486,80 +1502,25 @@ fail:
return -ENODEV;
}
-/* On 4m, find the associated dma for the lance chip */
-static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev)
-{
- struct sbus_dma *p;
-
- for_each_dvma(p) {
- if (p->sdev == sdev)
- return p;
- }
- return NULL;
-}
-
-#ifdef CONFIG_SUN4
-
-#include <asm/sun4paddr.h>
-#include <asm/machines.h>
-
-/* Find all the lance cards on the system and initialize them */
-static struct sbus_dev sun4_sdev;
-static int __devinit sparc_lance_init(void)
-{
- if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
- (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
- memset(&sun4_sdev, 0, sizeof(struct sbus_dev));
- sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
- sun4_sdev.irqs[0] = 6;
- return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
- }
- return -ENODEV;
-}
-
-static int __exit sunlance_sun4_remove(void)
+static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match)
{
- struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
- struct net_device *net_dev = lp->dev;
-
- unregister_netdev(net_dev);
-
- lance_free_hwresources(lp);
-
- free_netdev(net_dev);
-
- dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL);
-
- return 0;
-}
-
-#else /* !CONFIG_SUN4 */
-
-static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
-{
- struct sbus_dev *sdev = to_sbus_device(&dev->dev);
+ struct of_device *parent = to_of_device(op->dev.parent);
+ struct device_node *parent_dp = parent->node;
int err;
- if (sdev->parent) {
- struct of_device *parent = &sdev->parent->ofdev;
-
- if (!strcmp(parent->node->name, "ledma")) {
- struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev));
-
- err = sparc_lance_probe_one(sdev, ledma, NULL);
- } else if (!strcmp(parent->node->name, "lebuffer")) {
- err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev));
- } else
- err = sparc_lance_probe_one(sdev, NULL, NULL);
+ if (!strcmp(parent_dp->name, "ledma")) {
+ err = sparc_lance_probe_one(op, parent, NULL);
+ } else if (!strcmp(parent_dp->name, "lebuffer")) {
+ err = sparc_lance_probe_one(op, NULL, parent);
} else
- err = sparc_lance_probe_one(sdev, NULL, NULL);
+ err = sparc_lance_probe_one(op, NULL, NULL);
return err;
}
-static int __devexit sunlance_sbus_remove(struct of_device *dev)
+static int __devexit sunlance_sbus_remove(struct of_device *op)
{
- struct lance_private *lp = dev_get_drvdata(&dev->dev);
+ struct lance_private *lp = dev_get_drvdata(&op->dev);
struct net_device *net_dev = lp->dev;
unregister_netdev(net_dev);
@@ -1568,12 +1529,12 @@ static int __devexit sunlance_sbus_remove(struct of_device *dev)
free_netdev(net_dev);
- dev_set_drvdata(&dev->dev, NULL);
+ dev_set_drvdata(&op->dev, NULL);
return 0;
}
-static struct of_device_id sunlance_sbus_match[] = {
+static const struct of_device_id sunlance_sbus_match[] = {
{
.name = "le",
},
@@ -1593,17 +1554,12 @@ static struct of_platform_driver sunlance_sbus_driver = {
/* Find all the lance cards on the system and initialize them */
static int __init sparc_lance_init(void)
{
- return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type);
+ return of_register_driver(&sunlance_sbus_driver, &of_bus_type);
}
-#endif /* !CONFIG_SUN4 */
static void __exit sparc_lance_exit(void)
{
-#ifdef CONFIG_SUN4
- sunlance_sun4_remove();
-#else
of_unregister_driver(&sunlance_sbus_driver);
-#endif
}
module_init(sparc_lance_init);
OpenPOWER on IntegriCloud