diff options
-rw-r--r-- | drivers/net/smc911x.c | 17 | ||||
-rw-r--r-- | drivers/net/smc911x.h | 81 | ||||
-rw-r--r-- | include/linux/smc911x.h | 12 |
3 files changed, 109 insertions, 1 deletions
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 2ca4db85f938..fc605f276c00 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
@@ -1819,6 +1819,7 @@ static int __init smc911x_probe(struct net_device *dev) | |||
1819 | int i, retval; | 1819 | int i, retval; |
1820 | unsigned int val, chip_id, revision; | 1820 | unsigned int val, chip_id, revision; |
1821 | const char *version_string; | 1821 | const char *version_string; |
1822 | unsigned long irq_flags; | ||
1822 | 1823 | ||
1823 | DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); | 1824 | DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); |
1824 | 1825 | ||
@@ -1985,9 +1986,15 @@ static int __init smc911x_probe(struct net_device *dev) | |||
1985 | lp->ctl_rfduplx = 1; | 1986 | lp->ctl_rfduplx = 1; |
1986 | lp->ctl_rspeed = 100; | 1987 | lp->ctl_rspeed = 100; |
1987 | 1988 | ||
1989 | #ifdef SMC_DYNAMIC_BUS_CONFIG | ||
1990 | irq_flags = lp->cfg.irq_flags; | ||
1991 | #else | ||
1992 | irq_flags = IRQF_SHARED | SMC_IRQ_SENSE; | ||
1993 | #endif | ||
1994 | |||
1988 | /* Grab the IRQ */ | 1995 | /* Grab the IRQ */ |
1989 | retval = request_irq(dev->irq, &smc911x_interrupt, | 1996 | retval = request_irq(dev->irq, &smc911x_interrupt, |
1990 | IRQF_SHARED | SMC_IRQ_SENSE, dev->name, dev); | 1997 | irq_flags, dev->name, dev); |
1991 | if (retval) | 1998 | if (retval) |
1992 | goto err_out; | 1999 | goto err_out; |
1993 | 2000 | ||
@@ -2057,6 +2064,7 @@ err_out: | |||
2057 | */ | 2064 | */ |
2058 | static int smc911x_drv_probe(struct platform_device *pdev) | 2065 | static int smc911x_drv_probe(struct platform_device *pdev) |
2059 | { | 2066 | { |
2067 | struct smc91x_platdata *pd = pdev->dev.platform_data; | ||
2060 | struct net_device *ndev; | 2068 | struct net_device *ndev; |
2061 | struct resource *res; | 2069 | struct resource *res; |
2062 | struct smc911x_local *lp; | 2070 | struct smc911x_local *lp; |
@@ -2090,6 +2098,13 @@ static int smc911x_drv_probe(struct platform_device *pdev) | |||
2090 | ndev->irq = platform_get_irq(pdev, 0); | 2098 | ndev->irq = platform_get_irq(pdev, 0); |
2091 | lp = netdev_priv(ndev); | 2099 | lp = netdev_priv(ndev); |
2092 | lp->netdev = ndev; | 2100 | lp->netdev = ndev; |
2101 | #ifdef SMC_DYNAMIC_BUS_CONFIG | ||
2102 | if (!pd) { | ||
2103 | ret = -EINVAL; | ||
2104 | goto release_both; | ||
2105 | } | ||
2106 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); | ||
2107 | #endif | ||
2093 | 2108 | ||
2094 | addr = ioremap(res->start, SMC911X_IO_EXTENT); | 2109 | addr = ioremap(res->start, SMC911X_IO_EXTENT); |
2095 | if (!addr) { | 2110 | if (!addr) { |
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h index 271a3e8cf683..266232271a72 100644 --- a/drivers/net/smc911x.h +++ b/drivers/net/smc911x.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #ifndef _SMC911X_H_ | 29 | #ifndef _SMC911X_H_ |
30 | #define _SMC911X_H_ | 30 | #define _SMC911X_H_ |
31 | 31 | ||
32 | #include <linux/smc911x.h> | ||
32 | /* | 33 | /* |
33 | * Use the DMA feature on PXA chips | 34 | * Use the DMA feature on PXA chips |
34 | */ | 35 | */ |
@@ -42,6 +43,12 @@ | |||
42 | #define SMC_USE_16BIT 0 | 43 | #define SMC_USE_16BIT 0 |
43 | #define SMC_USE_32BIT 1 | 44 | #define SMC_USE_32BIT 1 |
44 | #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW | 45 | #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW |
46 | #else | ||
47 | /* | ||
48 | * Default configuration | ||
49 | */ | ||
50 | |||
51 | #define SMC_DYNAMIC_BUS_CONFIG | ||
45 | #endif | 52 | #endif |
46 | 53 | ||
47 | /* store this information for the driver.. */ | 54 | /* store this information for the driver.. */ |
@@ -92,12 +99,84 @@ struct smc911x_local { | |||
92 | struct device *dev; | 99 | struct device *dev; |
93 | #endif | 100 | #endif |
94 | void __iomem *base; | 101 | void __iomem *base; |
102 | #ifdef SMC_DYNAMIC_BUS_CONFIG | ||
103 | struct smc911x_platdata cfg; | ||
104 | #endif | ||
95 | }; | 105 | }; |
96 | 106 | ||
97 | /* | 107 | /* |
98 | * Define the bus width specific IO macros | 108 | * Define the bus width specific IO macros |
99 | */ | 109 | */ |
100 | 110 | ||
111 | #ifdef SMC_DYNAMIC_BUS_CONFIG | ||
112 | static inline unsigned int SMC_inl(struct smc911x_local *lp, int reg) | ||
113 | { | ||
114 | void __iomem *ioaddr = lp->base + reg; | ||
115 | |||
116 | if (lp->cfg.flags & SMC911X_USE_32BIT) | ||
117 | return readl(ioaddr); | ||
118 | |||
119 | if (lp->cfg.flags & SMC911X_USE_16BIT) | ||
120 | return readw(ioaddr) | (readw(ioaddr + 2) << 16); | ||
121 | |||
122 | BUG(); | ||
123 | } | ||
124 | |||
125 | static inline void SMC_outl(unsigned int value, struct smc911x_local *lp, | ||
126 | int reg) | ||
127 | { | ||
128 | void __iomem *ioaddr = lp->base + reg; | ||
129 | |||
130 | if (lp->cfg.flags & SMC911X_USE_32BIT) { | ||
131 | writel(value, ioaddr); | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | if (lp->cfg.flags & SMC911X_USE_16BIT) { | ||
136 | writew(value & 0xffff, ioaddr); | ||
137 | writew(value >> 16, ioaddr + 2); | ||
138 | return; | ||
139 | } | ||
140 | |||
141 | BUG(); | ||
142 | } | ||
143 | |||
144 | static inline void SMC_insl(struct smc911x_local *lp, int reg, | ||
145 | void *addr, unsigned int count) | ||
146 | { | ||
147 | void __iomem *ioaddr = lp->base + reg; | ||
148 | |||
149 | if (lp->cfg.flags & SMC911X_USE_32BIT) { | ||
150 | readsl(ioaddr, addr, count); | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | if (lp->cfg.flags & SMC911X_USE_16BIT) { | ||
155 | readsw(ioaddr, addr, count * 2); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | BUG(); | ||
160 | } | ||
161 | |||
162 | static inline void SMC_outsl(struct smc911x_local *lp, int reg, | ||
163 | void *addr, unsigned int count) | ||
164 | { | ||
165 | void __iomem *ioaddr = lp->base + reg; | ||
166 | |||
167 | if (lp->cfg.flags & SMC911X_USE_32BIT) { | ||
168 | writesl(ioaddr, addr, count); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | if (lp->cfg.flags & SMC911X_USE_16BIT) { | ||
173 | writesw(ioaddr, addr, count * 2); | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | BUG(); | ||
178 | } | ||
179 | #else | ||
101 | #if SMC_USE_16BIT | 180 | #if SMC_USE_16BIT |
102 | #define SMC_inl(lp, r) ((readw((lp)->base + (r)) & 0xFFFF) + (readw((lp)->base + (r) + 2) << 16)) | 181 | #define SMC_inl(lp, r) ((readw((lp)->base + (r)) & 0xFFFF) + (readw((lp)->base + (r) + 2) << 16)) |
103 | #define SMC_outl(v, lp, r) \ | 182 | #define SMC_outl(v, lp, r) \ |
@@ -115,6 +194,8 @@ struct smc911x_local { | |||
115 | #define SMC_outsl(lp, r, p, l) writesl((int*)((lp)->base + (r)), p, l) | 194 | #define SMC_outsl(lp, r, p, l) writesl((int*)((lp)->base + (r)), p, l) |
116 | 195 | ||
117 | #endif /* SMC_USE_16BIT */ | 196 | #endif /* SMC_USE_16BIT */ |
197 | #endif /* SMC_DYNAMIC_BUS_CONFIG */ | ||
198 | |||
118 | 199 | ||
119 | #ifdef SMC_USE_PXA_DMA | 200 | #ifdef SMC_USE_PXA_DMA |
120 | #define SMC_USE_DMA | 201 | #define SMC_USE_DMA |
diff --git a/include/linux/smc911x.h b/include/linux/smc911x.h new file mode 100644 index 000000000000..b58f54c24183 --- /dev/null +++ b/include/linux/smc911x.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef __SMC911X_H__ | ||
2 | #define __SMC911X_H__ | ||
3 | |||
4 | #define SMC911X_USE_16BIT (1 << 0) | ||
5 | #define SMC911X_USE_32BIT (1 << 1) | ||
6 | |||
7 | struct smc911x_platdata { | ||
8 | unsigned long flags; | ||
9 | unsigned long irq_flags; /* IRQF_... */ | ||
10 | }; | ||
11 | |||
12 | #endif /* __SMC911X_H__ */ | ||