diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index de7a913c487cc84c77ee7c645536cd0408bdcb68..34bfc60e8074f7244057c6f3d645b5b0cfd8b10d 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 8310f1a073d86c68778b2b0e46ce651f96f1bcec..80fb80f39200d8adcf8160e3d753a641488f8caa 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 90434db72db2ef6720b1d281e1cf1daa4624f0a0..0dea9459a8e48424b7ed0ab9564c28e4fb6a32b6 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;
 };