aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Miao <eric.miao@marvell.com>2008-06-24 01:38:50 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-07-12 16:52:40 -0400
commit159198862adad7109bb347bb30a620f67beac45f (patch)
tree2e440d22fa40b41f37922d9c6f2011e07a5e446b
parentc4f0e76747e80578a8f7fddd82fd0ce8127bd2f8 (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.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};