summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/smc91x.c57
-rw-r--r--drivers/net/smc91x.h3
-rw-r--r--include/linux/smc91x.h7
3 files changed, 41 insertions, 26 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index de7a913c487c..34bfc60e8074 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -2050,9 +2050,11 @@ static int smc_enable_device(struct platform_device *pdev)
return 0;
}
-static int smc_request_attrib(struct platform_device *pdev)
+static int smc_request_attrib(struct platform_device *pdev,
+ struct net_device *ndev)
{
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+ struct smc_local *lp = netdev_priv(ndev);
if (!res)
return 0;
@@ -2063,9 +2065,11 @@ static int smc_request_attrib(struct platform_device *pdev)
return 0;
}
-static void smc_release_attrib(struct platform_device *pdev)
+static void smc_release_attrib(struct platform_device *pdev,
+ struct net_device *ndev)
{
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+ struct smc_local *lp = netdev_priv(ndev);
if (res)
release_mem_region(res->start, ATTRIB_SIZE);
@@ -2126,25 +2130,11 @@ static int smc_drv_probe(struct platform_device *pdev)
unsigned long irq_flags = SMC_IRQ_FLAGS;
int ret;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
- if (!res)
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENODEV;
- goto out;
- }
-
-
- if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
- ret = -EBUSY;
- goto out;
- }
-
ndev = alloc_etherdev(sizeof(struct smc_local));
if (!ndev) {
printk("%s: could not allocate device.\n", CARDNAME);
ret = -ENOMEM;
- goto out_release_io;
+ goto out;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
@@ -2154,9 +2144,10 @@ static int smc_drv_probe(struct platform_device *pdev)
lp = netdev_priv(ndev);
- if (pd)
+ if (pd) {
memcpy(&lp->cfg, pd, sizeof(lp->cfg));
- else {
+ lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags);
+ } else {
lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0;
lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0;
lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0;
@@ -2165,10 +2156,24 @@ static int smc_drv_probe(struct platform_device *pdev)
ndev->dma = (unsigned char)-1;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
+ if (!res)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENODEV;
+ goto out_free_netdev;
+ }
+
+
+ if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
+ ret = -EBUSY;
+ goto out_free_netdev;
+ }
+
ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!ires) {
ret = -ENODEV;
- goto out_free_netdev;
+ goto out_release_io;
}
ndev->irq = ires->start;
@@ -2176,9 +2181,9 @@ static int smc_drv_probe(struct platform_device *pdev)
if (ires->flags & IRQF_TRIGGER_MASK)
irq_flags = ires->flags & IRQF_TRIGGER_MASK;
- ret = smc_request_attrib(pdev);
+ ret = smc_request_attrib(pdev, ndev);
if (ret)
- goto out_free_netdev;
+ goto out_release_io;
#if defined(CONFIG_SA1100_ASSABET)
NCR_0 |= NCR_ENET_OSC_EN;
#endif
@@ -2213,11 +2218,11 @@ static int smc_drv_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
iounmap(addr);
out_release_attrib:
- smc_release_attrib(pdev);
- out_free_netdev:
- free_netdev(ndev);
+ smc_release_attrib(pdev, ndev);
out_release_io:
release_mem_region(res->start, SMC_IO_EXTENT);
+ out_free_netdev:
+ free_netdev(ndev);
out:
printk("%s: not found (%d).\n", CARDNAME, ret);
@@ -2243,7 +2248,7 @@ static int smc_drv_remove(struct platform_device *pdev)
iounmap(lp->base);
smc_release_datacs(pdev,ndev);
- smc_release_attrib(pdev);
+ smc_release_attrib(pdev,ndev);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
if (!res)
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 8310f1a073d8..80fb80f39200 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -500,6 +500,9 @@ struct smc_local {
void __iomem *base;
void __iomem *datacs;
+ /* the low address lines on some platforms aren't connected... */
+ int io_shift;
+
struct smc91x_platdata cfg;
};
diff --git a/include/linux/smc91x.h b/include/linux/smc91x.h
index 90434db72db2..0dea9459a8e4 100644
--- a/include/linux/smc91x.h
+++ b/include/linux/smc91x.h
@@ -7,6 +7,13 @@
#define SMC91X_NOWAIT (1 << 3)
+/* two bits for IO_SHIFT, let's hope later designs will keep this sane */
+#define SMC91X_IO_SHIFT_0 (0 << 4)
+#define SMC91X_IO_SHIFT_1 (1 << 4)
+#define SMC91X_IO_SHIFT_2 (2 << 4)
+#define SMC91X_IO_SHIFT_3 (3 << 4)
+#define SMC91X_IO_SHIFT(x) (((x) >> 4) & 0x3)
+
struct smc91x_platdata {
unsigned long flags;
};