aboutsummaryrefslogtreecommitdiffstats
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)
2050 return 0; 2050 return 0;
2051} 2051}
2052 2052
2053static int smc_request_attrib(struct platform_device *pdev) 2053static int smc_request_attrib(struct platform_device *pdev,
2054 struct net_device *ndev)
2054{ 2055{
2055 struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); 2056 struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
2057 struct smc_local *lp = netdev_priv(ndev);
2056 2058
2057 if (!res) 2059 if (!res)
2058 return 0; 2060 return 0;
@@ -2063,9 +2065,11 @@ static int smc_request_attrib(struct platform_device *pdev)
2063 return 0; 2065 return 0;
2064} 2066}
2065 2067
2066static void smc_release_attrib(struct platform_device *pdev) 2068static void smc_release_attrib(struct platform_device *pdev,
2069 struct net_device *ndev)
2067{ 2070{
2068 struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); 2071 struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
2072 struct smc_local *lp = netdev_priv(ndev);
2069 2073
2070 if (res) 2074 if (res)
2071 release_mem_region(res->start, ATTRIB_SIZE); 2075 release_mem_region(res->start, ATTRIB_SIZE);
@@ -2126,25 +2130,11 @@ static int smc_drv_probe(struct platform_device *pdev)
2126 unsigned long irq_flags = SMC_IRQ_FLAGS; 2130 unsigned long irq_flags = SMC_IRQ_FLAGS;
2127 int ret; 2131 int ret;
2128 2132
2129 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
2130 if (!res)
2131 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2132 if (!res) {
2133 ret = -ENODEV;
2134 goto out;
2135 }
2136
2137
2138 if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
2139 ret = -EBUSY;
2140 goto out;
2141 }
2142
2143 ndev = alloc_etherdev(sizeof(struct smc_local)); 2133 ndev = alloc_etherdev(sizeof(struct smc_local));
2144 if (!ndev) { 2134 if (!ndev) {
2145 printk("%s: could not allocate device.\n", CARDNAME); 2135 printk("%s: could not allocate device.\n", CARDNAME);
2146 ret = -ENOMEM; 2136 ret = -ENOMEM;
2147 goto out_release_io; 2137 goto out;
2148 } 2138 }
2149 SET_NETDEV_DEV(ndev, &pdev->dev); 2139 SET_NETDEV_DEV(ndev, &pdev->dev);
2150 2140
@@ -2154,9 +2144,10 @@ static int smc_drv_probe(struct platform_device *pdev)
2154 2144
2155 lp = netdev_priv(ndev); 2145 lp = netdev_priv(ndev);
2156 2146
2157 if (pd) 2147 if (pd) {
2158 memcpy(&lp->cfg, pd, sizeof(lp->cfg)); 2148 memcpy(&lp->cfg, pd, sizeof(lp->cfg));
2159 else { 2149 lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags);
2150 } else {
2160 lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; 2151 lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0;
2161 lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; 2152 lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0;
2162 lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; 2153 lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0;
@@ -2165,10 +2156,24 @@ static int smc_drv_probe(struct platform_device *pdev)
2165 2156
2166 ndev->dma = (unsigned char)-1; 2157 ndev->dma = (unsigned char)-1;
2167 2158
2159 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
2160 if (!res)
2161 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2162 if (!res) {
2163 ret = -ENODEV;
2164 goto out_free_netdev;
2165 }
2166
2167
2168 if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
2169 ret = -EBUSY;
2170 goto out_free_netdev;
2171 }
2172
2168 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 2173 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
2169 if (!ires) { 2174 if (!ires) {
2170 ret = -ENODEV; 2175 ret = -ENODEV;
2171 goto out_free_netdev; 2176 goto out_release_io;
2172 } 2177 }
2173 2178
2174 ndev->irq = ires->start; 2179 ndev->irq = ires->start;
@@ -2176,9 +2181,9 @@ static int smc_drv_probe(struct platform_device *pdev)
2176 if (ires->flags & IRQF_TRIGGER_MASK) 2181 if (ires->flags & IRQF_TRIGGER_MASK)
2177 irq_flags = ires->flags & IRQF_TRIGGER_MASK; 2182 irq_flags = ires->flags & IRQF_TRIGGER_MASK;
2178 2183
2179 ret = smc_request_attrib(pdev); 2184 ret = smc_request_attrib(pdev, ndev);
2180 if (ret) 2185 if (ret)
2181 goto out_free_netdev; 2186 goto out_release_io;
2182#if defined(CONFIG_SA1100_ASSABET) 2187#if defined(CONFIG_SA1100_ASSABET)
2183 NCR_0 |= NCR_ENET_OSC_EN; 2188 NCR_0 |= NCR_ENET_OSC_EN;
2184#endif 2189#endif
@@ -2213,11 +2218,11 @@ static int smc_drv_probe(struct platform_device *pdev)
2213 platform_set_drvdata(pdev, NULL); 2218 platform_set_drvdata(pdev, NULL);
2214 iounmap(addr); 2219 iounmap(addr);
2215 out_release_attrib: 2220 out_release_attrib:
2216 smc_release_attrib(pdev); 2221 smc_release_attrib(pdev, ndev);
2217 out_free_netdev:
2218 free_netdev(ndev);
2219 out_release_io: 2222 out_release_io:
2220 release_mem_region(res->start, SMC_IO_EXTENT); 2223 release_mem_region(res->start, SMC_IO_EXTENT);
2224 out_free_netdev:
2225 free_netdev(ndev);
2221 out: 2226 out:
2222 printk("%s: not found (%d).\n", CARDNAME, ret); 2227 printk("%s: not found (%d).\n", CARDNAME, ret);
2223 2228
@@ -2243,7 +2248,7 @@ static int smc_drv_remove(struct platform_device *pdev)
2243 iounmap(lp->base); 2248 iounmap(lp->base);
2244 2249
2245 smc_release_datacs(pdev,ndev); 2250 smc_release_datacs(pdev,ndev);
2246 smc_release_attrib(pdev); 2251 smc_release_attrib(pdev,ndev);
2247 2252
2248 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); 2253 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
2249 if (!res) 2254 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 {
500 void __iomem *base; 500 void __iomem *base;
501 void __iomem *datacs; 501 void __iomem *datacs;
502 502
503 /* the low address lines on some platforms aren't connected... */
504 int io_shift;
505
503 struct smc91x_platdata cfg; 506 struct smc91x_platdata cfg;
504}; 507};
505 508
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 @@
7 7
8#define SMC91X_NOWAIT (1 << 3) 8#define SMC91X_NOWAIT (1 << 3)
9 9
10/* two bits for IO_SHIFT, let's hope later designs will keep this sane */
11#define SMC91X_IO_SHIFT_0 (0 << 4)
12#define SMC91X_IO_SHIFT_1 (1 << 4)
13#define SMC91X_IO_SHIFT_2 (2 << 4)
14#define SMC91X_IO_SHIFT_3 (3 << 4)
15#define SMC91X_IO_SHIFT(x) (((x) >> 4) & 0x3)
16
10struct smc91x_platdata { 17struct smc91x_platdata {
11 unsigned long flags; 18 unsigned long flags;
12}; 19};