diff options
-rw-r--r-- | drivers/net/smc91x.c | 57 | ||||
-rw-r--r-- | drivers/net/smc91x.h | 3 | ||||
-rw-r--r-- | include/linux/smc91x.h | 7 |
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 | ||
2053 | static int smc_request_attrib(struct platform_device *pdev) | 2053 | static 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 | ||
2066 | static void smc_release_attrib(struct platform_device *pdev) | 2068 | static 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 | |||
10 | struct smc91x_platdata { | 17 | struct smc91x_platdata { |
11 | unsigned long flags; | 18 | unsigned long flags; |
12 | }; | 19 | }; |