diff options
author | Eric Miao <eric.miao@marvell.com> | 2008-06-24 01:38:50 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-07-12 16:52:40 -0400 |
commit | 159198862adad7109bb347bb30a620f67beac45f (patch) | |
tree | 2e440d22fa40b41f37922d9c6f2011e07a5e446b | |
parent | c4f0e76747e80578a8f7fddd82fd0ce8127bd2f8 (diff) |
[NET] smc91x: prepare for SMC_IO_SHIFT to be a platform configurable variable
Now one can use the following code
#define SMC_IO_SHIFT lp->io_shift
to make SMC_IO_SHIFT a variable. This, however, will slightly increase
the CPU overhead and have negative impact on the network performance.
The tradeoff is, this can be specified in the smc91x platform data so
that multiple boards support can be built in a single zImage.
Signed-off-by: Eric Miao <eric.miao@marvell.com>
Acked-by: Nicolas Pitre <nico@cam.org>
Acked-by: Jeff Garzik <jgarzik@pobox.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-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 | }; |