aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/smc911x.c17
-rw-r--r--drivers/net/smc911x.h81
2 files changed, 97 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 */
2058static int smc911x_drv_probe(struct platform_device *pdev) 2065static 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
112static 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
125static 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
144static 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
162static 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