aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-10-04 16:10:28 -0400
committerLuciano Coelho <coelho@ti.com>2011-10-11 09:00:46 -0400
commitfbe936bcb59d8e6e054c325a441082b55538bf8f (patch)
treeb2ad087630dafef90bc89fcdf2dfa2b3c1b8cf81
parentc7e7c227b63836933ef736fa2d7cc526174b1563 (diff)
wl12xx: add an sdio glue struct to keep wl and device side-by-side
In order to fully abstract the bus, we need to save the device structure *beside* wl1271, instead of inside it. This will help re-structuring the driver so that we avoid the duplicated code in the bus modules. Signed-off-by: Felipe Balbi <balbi@ti.com> [forward-ported and cleaned up and rephrased commit message] Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index 516a8980723c..5a4268012da4 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -44,6 +44,11 @@
44#define SDIO_DEVICE_ID_TI_WL1271 0x4076 44#define SDIO_DEVICE_ID_TI_WL1271 0x4076
45#endif 45#endif
46 46
47struct wl12xx_sdio_glue {
48 struct device *dev;
49 struct wl1271 *wl;
50};
51
47static const struct sdio_device_id wl1271_devices[] __devinitconst = { 52static const struct sdio_device_id wl1271_devices[] __devinitconst = {
48 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, 53 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
49 {} 54 {}
@@ -57,14 +62,14 @@ static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz)
57 sdio_release_host(wl->if_priv); 62 sdio_release_host(wl->if_priv);
58} 63}
59 64
60static inline struct sdio_func *wl_to_func(struct wl1271 *wl) 65static inline struct wl12xx_sdio_glue *wl_to_glue(struct wl1271 *wl)
61{ 66{
62 return wl->if_priv; 67 return wl->if_priv;
63} 68}
64 69
65static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) 70static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
66{ 71{
67 return &(wl_to_func(wl)->dev); 72 return wl_to_glue(wl)->dev;
68} 73}
69 74
70static irqreturn_t wl1271_hardirq(int irq, void *cookie) 75static irqreturn_t wl1271_hardirq(int irq, void *cookie)
@@ -110,7 +115,8 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
110 size_t len, bool fixed) 115 size_t len, bool fixed)
111{ 116{
112 int ret; 117 int ret;
113 struct sdio_func *func = wl_to_func(wl); 118 struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
119 struct sdio_func *func = dev_to_sdio_func(glue->dev);
114 120
115 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 121 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
116 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); 122 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
@@ -135,7 +141,8 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
135 size_t len, bool fixed) 141 size_t len, bool fixed)
136{ 142{
137 int ret; 143 int ret;
138 struct sdio_func *func = wl_to_func(wl); 144 struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
145 struct sdio_func *func = dev_to_sdio_func(glue->dev);
139 146
140 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 147 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
141 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); 148 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
@@ -158,8 +165,9 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
158 165
159static int wl1271_sdio_power_on(struct wl1271 *wl) 166static int wl1271_sdio_power_on(struct wl1271 *wl)
160{ 167{
161 struct sdio_func *func = wl_to_func(wl);
162 int ret; 168 int ret;
169 struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
170 struct sdio_func *func = dev_to_sdio_func(glue->dev);
163 171
164 /* If enabled, tell runtime PM not to power off the card */ 172 /* If enabled, tell runtime PM not to power off the card */
165 if (pm_runtime_enabled(&func->dev)) { 173 if (pm_runtime_enabled(&func->dev)) {
@@ -182,8 +190,9 @@ out:
182 190
183static int wl1271_sdio_power_off(struct wl1271 *wl) 191static int wl1271_sdio_power_off(struct wl1271 *wl)
184{ 192{
185 struct sdio_func *func = wl_to_func(wl);
186 int ret; 193 int ret;
194 struct wl12xx_sdio_glue *glue = wl_to_glue(wl);
195 struct sdio_func *func = dev_to_sdio_func(glue->dev);
187 196
188 sdio_disable_func(func); 197 sdio_disable_func(func);
189 sdio_release_host(func); 198 sdio_release_host(func);
@@ -224,21 +233,34 @@ static int __devinit wl1271_probe(struct sdio_func *func,
224 struct ieee80211_hw *hw; 233 struct ieee80211_hw *hw;
225 const struct wl12xx_platform_data *wlan_data; 234 const struct wl12xx_platform_data *wlan_data;
226 struct wl1271 *wl; 235 struct wl1271 *wl;
236 struct wl12xx_sdio_glue *glue;
227 unsigned long irqflags; 237 unsigned long irqflags;
228 mmc_pm_flag_t mmcflags; 238 mmc_pm_flag_t mmcflags;
229 int ret; 239 int ret = -ENOMEM;
230 240
231 /* We are only able to handle the wlan function */ 241 /* We are only able to handle the wlan function */
232 if (func->num != 0x02) 242 if (func->num != 0x02)
233 return -ENODEV; 243 return -ENODEV;
234 244
245 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
246 if (!glue) {
247 wl1271_error("can't allocate glue");
248 goto out;
249 }
250
235 hw = wl1271_alloc_hw(); 251 hw = wl1271_alloc_hw();
236 if (IS_ERR(hw)) 252 if (IS_ERR(hw)) {
237 return PTR_ERR(hw); 253 wl1271_error("can't allocate hw");
254 ret = PTR_ERR(hw);
255 goto out_free_glue;
256 }
238 257
239 wl = hw->priv; 258 wl = hw->priv;
240 259
241 wl->if_priv = func; 260 glue->dev = &func->dev;
261 glue->wl = wl;
262
263 wl->if_priv = glue;
242 wl->if_ops = &sdio_ops; 264 wl->if_ops = &sdio_ops;
243 265
244 /* Grab access to FN0 for ELP reg. */ 266 /* Grab access to FN0 for ELP reg. */
@@ -251,7 +273,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
251 if (IS_ERR(wlan_data)) { 273 if (IS_ERR(wlan_data)) {
252 ret = PTR_ERR(wlan_data); 274 ret = PTR_ERR(wlan_data);
253 wl1271_error("missing wlan platform data: %d", ret); 275 wl1271_error("missing wlan platform data: %d", ret);
254 goto out_free; 276 goto out_free_hw;
255 } 277 }
256 278
257 wl->irq = wlan_data->irq; 279 wl->irq = wlan_data->irq;
@@ -269,7 +291,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
269 DRIVER_NAME, wl); 291 DRIVER_NAME, wl);
270 if (ret < 0) { 292 if (ret < 0) {
271 wl1271_error("request_irq() failed: %d", ret); 293 wl1271_error("request_irq() failed: %d", ret);
272 goto out_free; 294 goto out_free_hw;
273 } 295 }
274 296
275 ret = enable_irq_wake(wl->irq); 297 ret = enable_irq_wake(wl->irq);
@@ -294,25 +316,29 @@ static int __devinit wl1271_probe(struct sdio_func *func,
294 if (ret) 316 if (ret)
295 goto out_irq; 317 goto out_irq;
296 318
297 sdio_set_drvdata(func, wl); 319 sdio_set_drvdata(func, glue);
298 320
299 /* Tell PM core that we don't need the card to be powered now */ 321 /* Tell PM core that we don't need the card to be powered now */
300 pm_runtime_put_noidle(&func->dev); 322 pm_runtime_put_noidle(&func->dev);
301 323
302 return 0; 324 return 0;
303 325
304 out_irq: 326out_irq:
305 free_irq(wl->irq, wl); 327 free_irq(wl->irq, wl);
306 328
307 out_free: 329out_free_hw:
308 wl1271_free_hw(wl); 330 wl1271_free_hw(wl);
309 331
332out_free_glue:
333 kfree(glue);
334out:
310 return ret; 335 return ret;
311} 336}
312 337
313static void __devexit wl1271_remove(struct sdio_func *func) 338static void __devexit wl1271_remove(struct sdio_func *func)
314{ 339{
315 struct wl1271 *wl = sdio_get_drvdata(func); 340 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
341 struct wl1271 *wl = glue->wl;
316 342
317 /* Undo decrement done above in wl1271_probe */ 343 /* Undo decrement done above in wl1271_probe */
318 pm_runtime_get_noresume(&func->dev); 344 pm_runtime_get_noresume(&func->dev);
@@ -324,6 +350,7 @@ static void __devexit wl1271_remove(struct sdio_func *func)
324 } 350 }
325 free_irq(wl->irq, wl); 351 free_irq(wl->irq, wl);
326 wl1271_free_hw(wl); 352 wl1271_free_hw(wl);
353 kfree(glue);
327} 354}
328 355
329#ifdef CONFIG_PM 356#ifdef CONFIG_PM