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 | }; |
