aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <magnus.damm@gmail.com>2008-02-22 05:55:15 -0500
committerJeff Garzik <jeff@garzik.org>2008-03-17 07:49:27 -0400
commit3e94794355724f77dc6cbb5ad956f7c72d8313a4 (patch)
tree9a8bf2a3c2ead985b9f386fb196db0918da48270
parentcfdfa86536d2fbc8102780ec15faea185e957d3d (diff)
smc91x: introduce platform data flags V2
This patch introduces struct smc91x_platdata and modifies the driver so bus width is checked during run time using SMC_nBIT() instead of SMC_CAN_USE_nBIT. V2 keeps static configuration lean using SMC_DYNAMIC_BUS_CONFIG. Signed-off-by: Magnus Damm <damm@igel.co.jp> Acked-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/smc91x.c34
-rw-r--r--drivers/net/smc91x.h57
-rw-r--r--include/linux/smc91x.h13
3 files changed, 77 insertions, 27 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index d0ef80ae018a..97bdb2a43bc8 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1997,6 +1997,8 @@ err_out:
1997 1997
1998static int smc_enable_device(struct platform_device *pdev) 1998static int smc_enable_device(struct platform_device *pdev)
1999{ 1999{
2000 struct net_device *ndev = platform_get_drvdata(pdev);
2001 struct smc_local *lp = netdev_priv(ndev);
2000 unsigned long flags; 2002 unsigned long flags;
2001 unsigned char ecor, ecsr; 2003 unsigned char ecor, ecsr;
2002 void __iomem *addr; 2004 void __iomem *addr;
@@ -2039,7 +2041,7 @@ static int smc_enable_device(struct platform_device *pdev)
2039 * Set the appropriate byte/word mode. 2041 * Set the appropriate byte/word mode.
2040 */ 2042 */
2041 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; 2043 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8;
2042 if (!SMC_CAN_USE_16BIT) 2044 if (!SMC_16BIT(lp))
2043 ecsr |= ECSR_IOIS8; 2045 ecsr |= ECSR_IOIS8;
2044 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); 2046 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT));
2045 local_irq_restore(flags); 2047 local_irq_restore(flags);
@@ -2124,10 +2126,11 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
2124 */ 2126 */
2125static int smc_drv_probe(struct platform_device *pdev) 2127static int smc_drv_probe(struct platform_device *pdev)
2126{ 2128{
2129 struct smc91x_platdata *pd = pdev->dev.platform_data;
2130 struct smc_local *lp;
2127 struct net_device *ndev; 2131 struct net_device *ndev;
2128 struct resource *res, *ires; 2132 struct resource *res, *ires;
2129 unsigned int __iomem *addr; 2133 unsigned int __iomem *addr;
2130 unsigned long irq_flags = SMC_IRQ_FLAGS;
2131 int ret; 2134 int ret;
2132 2135
2133 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); 2136 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
@@ -2152,6 +2155,27 @@ static int smc_drv_probe(struct platform_device *pdev)
2152 } 2155 }
2153 SET_NETDEV_DEV(ndev, &pdev->dev); 2156 SET_NETDEV_DEV(ndev, &pdev->dev);
2154 2157
2158 /* get configuration from platform data, only allow use of
2159 * bus width if both SMC_CAN_USE_xxx and SMC91X_USE_xxx are set.
2160 */
2161
2162 lp = netdev_priv(ndev);
2163 lp->cfg.irq_flags = SMC_IRQ_FLAGS;
2164
2165#ifdef SMC_DYNAMIC_BUS_CONFIG
2166 if (pd)
2167 memcpy(&lp->cfg, pd, sizeof(lp->cfg));
2168 else {
2169 lp->cfg.flags = SMC91X_USE_8BIT;
2170 lp->cfg.flags |= SMC91X_USE_16BIT;
2171 lp->cfg.flags |= SMC91X_USE_32BIT;
2172 }
2173
2174 lp->cfg.flags &= ~(SMC_CAN_USE_8BIT ? 0 : SMC91X_USE_8BIT);
2175 lp->cfg.flags &= ~(SMC_CAN_USE_16BIT ? 0 : SMC91X_USE_16BIT);
2176 lp->cfg.flags &= ~(SMC_CAN_USE_32BIT ? 0 : SMC91X_USE_32BIT);
2177#endif
2178
2155 ndev->dma = (unsigned char)-1; 2179 ndev->dma = (unsigned char)-1;
2156 2180
2157 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 2181 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -2162,7 +2186,7 @@ static int smc_drv_probe(struct platform_device *pdev)
2162 2186
2163 ndev->irq = ires->start; 2187 ndev->irq = ires->start;
2164 if (SMC_IRQ_FLAGS == -1) 2188 if (SMC_IRQ_FLAGS == -1)
2165 irq_flags = ires->flags & IRQF_TRIGGER_MASK; 2189 lp->cfg.irq_flags = ires->flags & IRQF_TRIGGER_MASK;
2166 2190
2167 ret = smc_request_attrib(pdev); 2191 ret = smc_request_attrib(pdev);
2168 if (ret) 2192 if (ret)
@@ -2170,6 +2194,7 @@ static int smc_drv_probe(struct platform_device *pdev)
2170#if defined(CONFIG_SA1100_ASSABET) 2194#if defined(CONFIG_SA1100_ASSABET)
2171 NCR_0 |= NCR_ENET_OSC_EN; 2195 NCR_0 |= NCR_ENET_OSC_EN;
2172#endif 2196#endif
2197 platform_set_drvdata(pdev, ndev);
2173 ret = smc_enable_device(pdev); 2198 ret = smc_enable_device(pdev);
2174 if (ret) 2199 if (ret)
2175 goto out_release_attrib; 2200 goto out_release_attrib;
@@ -2188,8 +2213,7 @@ static int smc_drv_probe(struct platform_device *pdev)
2188 } 2213 }
2189#endif 2214#endif
2190 2215
2191 platform_set_drvdata(pdev, ndev); 2216 ret = smc_probe(ndev, addr, lp->cfg.irq_flags);
2192 ret = smc_probe(ndev, addr, irq_flags);
2193 if (ret != 0) 2217 if (ret != 0)
2194 goto out_iounmap; 2218 goto out_iounmap;
2195 2219
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 92ff9c42367e..e044b4de1397 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -34,6 +34,7 @@
34#ifndef _SMC91X_H_ 34#ifndef _SMC91X_H_
35#define _SMC91X_H_ 35#define _SMC91X_H_
36 36
37#include <linux/smc91x.h>
37 38
38/* 39/*
39 * Define your architecture specific bus configuration parameters here. 40 * Define your architecture specific bus configuration parameters here.
@@ -481,6 +482,7 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
481#define RPC_LSA_DEFAULT RPC_LED_100_10 482#define RPC_LSA_DEFAULT RPC_LED_100_10
482#define RPC_LSB_DEFAULT RPC_LED_TX_RX 483#define RPC_LSB_DEFAULT RPC_LED_TX_RX
483 484
485#define SMC_DYNAMIC_BUS_CONFIG
484#endif 486#endif
485 487
486 488
@@ -526,8 +528,19 @@ struct smc_local {
526#endif 528#endif
527 void __iomem *base; 529 void __iomem *base;
528 void __iomem *datacs; 530 void __iomem *datacs;
531
532 struct smc91x_platdata cfg;
529}; 533};
530 534
535#ifdef SMC_DYNAMIC_BUS_CONFIG
536#define SMC_8BIT(p) (((p)->cfg.flags & SMC91X_USE_8BIT) && SMC_CAN_USE_8BIT)
537#define SMC_16BIT(p) (((p)->cfg.flags & SMC91X_USE_16BIT) && SMC_CAN_USE_16BIT)
538#define SMC_32BIT(p) (((p)->cfg.flags & SMC91X_USE_32BIT) && SMC_CAN_USE_32BIT)
539#else
540#define SMC_8BIT(p) SMC_CAN_USE_8BIT
541#define SMC_16BIT(p) SMC_CAN_USE_16BIT
542#define SMC_32BIT(p) SMC_CAN_USE_32BIT
543#endif
531 544
532#ifdef SMC_USE_PXA_DMA 545#ifdef SMC_USE_PXA_DMA
533/* 546/*
@@ -1108,41 +1121,41 @@ static const char * chip_ids[ 16 ] = {
1108 * 1121 *
1109 * Enforce it on any 32-bit capable setup for now. 1122 * Enforce it on any 32-bit capable setup for now.
1110 */ 1123 */
1111#define SMC_MUST_ALIGN_WRITE SMC_CAN_USE_32BIT 1124#define SMC_MUST_ALIGN_WRITE(lp) SMC_32BIT(lp)
1112 1125
1113#define SMC_GET_PN(lp) \ 1126#define SMC_GET_PN(lp) \
1114 (SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, PN_REG(lp))) \ 1127 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, PN_REG(lp))) \
1115 : (SMC_inw(ioaddr, PN_REG(lp)) & 0xFF)) 1128 : (SMC_inw(ioaddr, PN_REG(lp)) & 0xFF))
1116 1129
1117#define SMC_SET_PN(lp, x) \ 1130#define SMC_SET_PN(lp, x) \
1118 do { \ 1131 do { \
1119 if (SMC_MUST_ALIGN_WRITE) \ 1132 if (SMC_MUST_ALIGN_WRITE(lp)) \
1120 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 0, 2)); \ 1133 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 0, 2)); \
1121 else if (SMC_CAN_USE_8BIT) \ 1134 else if (SMC_8BIT(lp)) \
1122 SMC_outb(x, ioaddr, PN_REG(lp)); \ 1135 SMC_outb(x, ioaddr, PN_REG(lp)); \
1123 else \ 1136 else \
1124 SMC_outw(x, ioaddr, PN_REG(lp)); \ 1137 SMC_outw(x, ioaddr, PN_REG(lp)); \
1125 } while (0) 1138 } while (0)
1126 1139
1127#define SMC_GET_AR(lp) \ 1140#define SMC_GET_AR(lp) \
1128 (SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, AR_REG(lp))) \ 1141 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, AR_REG(lp))) \
1129 : (SMC_inw(ioaddr, PN_REG(lp)) >> 8)) 1142 : (SMC_inw(ioaddr, PN_REG(lp)) >> 8))
1130 1143
1131#define SMC_GET_TXFIFO(lp) \ 1144#define SMC_GET_TXFIFO(lp) \
1132 (SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, TXFIFO_REG(lp))) \ 1145 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, TXFIFO_REG(lp))) \
1133 : (SMC_inw(ioaddr, TXFIFO_REG(lp)) & 0xFF)) 1146 : (SMC_inw(ioaddr, TXFIFO_REG(lp)) & 0xFF))
1134 1147
1135#define SMC_GET_RXFIFO(lp) \ 1148#define SMC_GET_RXFIFO(lp) \
1136 (SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, RXFIFO_REG(lp))) \ 1149 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, RXFIFO_REG(lp))) \
1137 : (SMC_inw(ioaddr, TXFIFO_REG(lp)) >> 8)) 1150 : (SMC_inw(ioaddr, TXFIFO_REG(lp)) >> 8))
1138 1151
1139#define SMC_GET_INT(lp) \ 1152#define SMC_GET_INT(lp) \
1140 (SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, INT_REG(lp))) \ 1153 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, INT_REG(lp))) \
1141 : (SMC_inw(ioaddr, INT_REG(lp)) & 0xFF)) 1154 : (SMC_inw(ioaddr, INT_REG(lp)) & 0xFF))
1142 1155
1143#define SMC_ACK_INT(lp, x) \ 1156#define SMC_ACK_INT(lp, x) \
1144 do { \ 1157 do { \
1145 if (SMC_CAN_USE_8BIT) \ 1158 if (SMC_8BIT(lp)) \
1146 SMC_outb(x, ioaddr, INT_REG(lp)); \ 1159 SMC_outb(x, ioaddr, INT_REG(lp)); \
1147 else { \ 1160 else { \
1148 unsigned long __flags; \ 1161 unsigned long __flags; \
@@ -1155,12 +1168,12 @@ static const char * chip_ids[ 16 ] = {
1155 } while (0) 1168 } while (0)
1156 1169
1157#define SMC_GET_INT_MASK(lp) \ 1170#define SMC_GET_INT_MASK(lp) \
1158 (SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, IM_REG(lp))) \ 1171 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, IM_REG(lp))) \
1159 : (SMC_inw(ioaddr, INT_REG(lp)) >> 8)) 1172 : (SMC_inw(ioaddr, INT_REG(lp)) >> 8))
1160 1173
1161#define SMC_SET_INT_MASK(lp, x) \ 1174#define SMC_SET_INT_MASK(lp, x) \
1162 do { \ 1175 do { \
1163 if (SMC_CAN_USE_8BIT) \ 1176 if (SMC_8BIT(lp)) \
1164 SMC_outb(x, ioaddr, IM_REG(lp)); \ 1177 SMC_outb(x, ioaddr, IM_REG(lp)); \
1165 else \ 1178 else \
1166 SMC_outw((x) << 8, ioaddr, INT_REG(lp)); \ 1179 SMC_outw((x) << 8, ioaddr, INT_REG(lp)); \
@@ -1170,7 +1183,7 @@ static const char * chip_ids[ 16 ] = {
1170 1183
1171#define SMC_SELECT_BANK(lp, x) \ 1184#define SMC_SELECT_BANK(lp, x) \
1172 do { \ 1185 do { \
1173 if (SMC_MUST_ALIGN_WRITE) \ 1186 if (SMC_MUST_ALIGN_WRITE(lp)) \
1174 SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \ 1187 SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \
1175 else \ 1188 else \
1176 SMC_outw(x, ioaddr, BANK_SELECT); \ 1189 SMC_outw(x, ioaddr, BANK_SELECT); \
@@ -1208,7 +1221,7 @@ static const char * chip_ids[ 16 ] = {
1208 1221
1209#define SMC_SET_PTR(lp, x) \ 1222#define SMC_SET_PTR(lp, x) \
1210 do { \ 1223 do { \
1211 if (SMC_MUST_ALIGN_WRITE) \ 1224 if (SMC_MUST_ALIGN_WRITE(lp)) \
1212 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 4, 2)); \ 1225 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 4, 2)); \
1213 else \ 1226 else \
1214 SMC_outw(x, ioaddr, PTR_REG(lp)); \ 1227 SMC_outw(x, ioaddr, PTR_REG(lp)); \
@@ -1226,7 +1239,7 @@ static const char * chip_ids[ 16 ] = {
1226 1239
1227#define SMC_SET_RPC(lp, x) \ 1240#define SMC_SET_RPC(lp, x) \
1228 do { \ 1241 do { \
1229 if (SMC_MUST_ALIGN_WRITE) \ 1242 if (SMC_MUST_ALIGN_WRITE(lp)) \
1230 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 0)); \ 1243 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 0)); \
1231 else \ 1244 else \
1232 SMC_outw(x, ioaddr, RPC_REG(lp)); \ 1245 SMC_outw(x, ioaddr, RPC_REG(lp)); \
@@ -1267,7 +1280,7 @@ static const char * chip_ids[ 16 ] = {
1267 1280
1268#define SMC_PUT_PKT_HDR(lp, status, length) \ 1281#define SMC_PUT_PKT_HDR(lp, status, length) \
1269 do { \ 1282 do { \
1270 if (SMC_CAN_USE_32BIT) \ 1283 if (SMC_32BIT(lp)) \
1271 SMC_outl((status) | (length)<<16, ioaddr, \ 1284 SMC_outl((status) | (length)<<16, ioaddr, \
1272 DATA_REG(lp)); \ 1285 DATA_REG(lp)); \
1273 else { \ 1286 else { \
@@ -1278,7 +1291,7 @@ static const char * chip_ids[ 16 ] = {
1278 1291
1279#define SMC_GET_PKT_HDR(lp, status, length) \ 1292#define SMC_GET_PKT_HDR(lp, status, length) \
1280 do { \ 1293 do { \
1281 if (SMC_CAN_USE_32BIT) { \ 1294 if (SMC_32BIT(lp)) { \
1282 unsigned int __val = SMC_inl(ioaddr, DATA_REG(lp)); \ 1295 unsigned int __val = SMC_inl(ioaddr, DATA_REG(lp)); \
1283 (status) = __val & 0xffff; \ 1296 (status) = __val & 0xffff; \
1284 (length) = __val >> 16; \ 1297 (length) = __val >> 16; \
@@ -1290,7 +1303,7 @@ static const char * chip_ids[ 16 ] = {
1290 1303
1291#define SMC_PUSH_DATA(lp, p, l) \ 1304#define SMC_PUSH_DATA(lp, p, l) \
1292 do { \ 1305 do { \
1293 if (SMC_CAN_USE_32BIT) { \ 1306 if (SMC_32BIT(lp)) { \
1294 void *__ptr = (p); \ 1307 void *__ptr = (p); \
1295 int __len = (l); \ 1308 int __len = (l); \
1296 void __iomem *__ioaddr = ioaddr; \ 1309 void __iomem *__ioaddr = ioaddr; \
@@ -1308,15 +1321,15 @@ static const char * chip_ids[ 16 ] = {
1308 SMC_outw(*((u16 *)__ptr), ioaddr, \ 1321 SMC_outw(*((u16 *)__ptr), ioaddr, \
1309 DATA_REG(lp)); \ 1322 DATA_REG(lp)); \
1310 } \ 1323 } \
1311 } else if (SMC_CAN_USE_16BIT) \ 1324 } else if (SMC_16BIT(lp)) \
1312 SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ 1325 SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1); \
1313 else if (SMC_CAN_USE_8BIT) \ 1326 else if (SMC_8BIT(lp)) \
1314 SMC_outsb(ioaddr, DATA_REG(lp), p, l); \ 1327 SMC_outsb(ioaddr, DATA_REG(lp), p, l); \
1315 } while (0) 1328 } while (0)
1316 1329
1317#define SMC_PULL_DATA(lp, p, l) \ 1330#define SMC_PULL_DATA(lp, p, l) \
1318 do { \ 1331 do { \
1319 if (SMC_CAN_USE_32BIT) { \ 1332 if (SMC_32BIT(lp)) { \
1320 void *__ptr = (p); \ 1333 void *__ptr = (p); \
1321 int __len = (l); \ 1334 int __len = (l); \
1322 void __iomem *__ioaddr = ioaddr; \ 1335 void __iomem *__ioaddr = ioaddr; \
@@ -1343,9 +1356,9 @@ static const char * chip_ids[ 16 ] = {
1343 __ioaddr = lp->datacs; \ 1356 __ioaddr = lp->datacs; \
1344 __len += 2; \ 1357 __len += 2; \
1345 SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \ 1358 SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
1346 } else if (SMC_CAN_USE_16BIT) \ 1359 } else if (SMC_16BIT(lp)) \
1347 SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ 1360 SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1); \
1348 else if (SMC_CAN_USE_8BIT) \ 1361 else if (SMC_8BIT(lp)) \
1349 SMC_insb(ioaddr, DATA_REG(lp), p, l); \ 1362 SMC_insb(ioaddr, DATA_REG(lp), p, l); \
1350 } while (0) 1363 } while (0)
1351 1364
diff --git a/include/linux/smc91x.h b/include/linux/smc91x.h
new file mode 100644
index 000000000000..8e0556b8781c
--- /dev/null
+++ b/include/linux/smc91x.h
@@ -0,0 +1,13 @@
1#ifndef __SMC91X_H__
2#define __SMC91X_H__
3
4#define SMC91X_USE_8BIT (1 << 0)
5#define SMC91X_USE_16BIT (1 << 1)
6#define SMC91X_USE_32BIT (1 << 2)
7
8struct smc91x_platdata {
9 unsigned long flags;
10 unsigned long irq_flags; /* IRQF_... */
11};
12
13#endif /* __SMC91X_H__ */