diff options
author | Felipe Balbi <balbi@ti.com> | 2011-10-04 16:36:47 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-10-11 09:00:51 -0400 |
commit | b65019f661733ece3be0680be307d238d4dec68e (patch) | |
tree | 507d603a2b1034e6db12ff5759258a061c170c7a | |
parent | fbe936bcb59d8e6e054c325a441082b55538bf8f (diff) |
wl12xx: add an spi 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/spi.c | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 0f9718677860..16f0c71f6d4c 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c | |||
@@ -69,14 +69,19 @@ | |||
69 | 69 | ||
70 | #define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) | 70 | #define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) |
71 | 71 | ||
72 | static inline struct spi_device *wl_to_spi(struct wl1271 *wl) | 72 | struct wl12xx_spi_glue { |
73 | struct device *dev; | ||
74 | struct wl1271 *wl; | ||
75 | }; | ||
76 | |||
77 | static inline struct wl12xx_spi_glue *wl_to_glue(struct wl1271 *wl) | ||
73 | { | 78 | { |
74 | return wl->if_priv; | 79 | return wl->if_priv; |
75 | } | 80 | } |
76 | 81 | ||
77 | static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl) | 82 | static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl) |
78 | { | 83 | { |
79 | return &(wl_to_spi(wl)->dev); | 84 | return wl_to_glue(wl)->dev; |
80 | } | 85 | } |
81 | 86 | ||
82 | static void wl1271_spi_disable_interrupts(struct wl1271 *wl) | 87 | static void wl1271_spi_disable_interrupts(struct wl1271 *wl) |
@@ -91,6 +96,7 @@ static void wl1271_spi_enable_interrupts(struct wl1271 *wl) | |||
91 | 96 | ||
92 | static void wl1271_spi_reset(struct wl1271 *wl) | 97 | static void wl1271_spi_reset(struct wl1271 *wl) |
93 | { | 98 | { |
99 | struct wl12xx_spi_glue *glue = wl_to_glue(wl); | ||
94 | u8 *cmd; | 100 | u8 *cmd; |
95 | struct spi_transfer t; | 101 | struct spi_transfer t; |
96 | struct spi_message m; | 102 | struct spi_message m; |
@@ -110,7 +116,7 @@ static void wl1271_spi_reset(struct wl1271 *wl) | |||
110 | t.len = WSPI_INIT_CMD_LEN; | 116 | t.len = WSPI_INIT_CMD_LEN; |
111 | spi_message_add_tail(&t, &m); | 117 | spi_message_add_tail(&t, &m); |
112 | 118 | ||
113 | spi_sync(wl_to_spi(wl), &m); | 119 | spi_sync(to_spi_device(glue->dev), &m); |
114 | 120 | ||
115 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); | 121 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); |
116 | kfree(cmd); | 122 | kfree(cmd); |
@@ -118,6 +124,7 @@ static void wl1271_spi_reset(struct wl1271 *wl) | |||
118 | 124 | ||
119 | static void wl1271_spi_init(struct wl1271 *wl) | 125 | static void wl1271_spi_init(struct wl1271 *wl) |
120 | { | 126 | { |
127 | struct wl12xx_spi_glue *glue = wl_to_glue(wl); | ||
121 | u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; | 128 | u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; |
122 | struct spi_transfer t; | 129 | struct spi_transfer t; |
123 | struct spi_message m; | 130 | struct spi_message m; |
@@ -165,7 +172,7 @@ static void wl1271_spi_init(struct wl1271 *wl) | |||
165 | t.len = WSPI_INIT_CMD_LEN; | 172 | t.len = WSPI_INIT_CMD_LEN; |
166 | spi_message_add_tail(&t, &m); | 173 | spi_message_add_tail(&t, &m); |
167 | 174 | ||
168 | spi_sync(wl_to_spi(wl), &m); | 175 | spi_sync(to_spi_device(glue->dev), &m); |
169 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); | 176 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); |
170 | kfree(cmd); | 177 | kfree(cmd); |
171 | } | 178 | } |
@@ -174,6 +181,7 @@ static void wl1271_spi_init(struct wl1271 *wl) | |||
174 | 181 | ||
175 | static int wl1271_spi_read_busy(struct wl1271 *wl) | 182 | static int wl1271_spi_read_busy(struct wl1271 *wl) |
176 | { | 183 | { |
184 | struct wl12xx_spi_glue *glue = wl_to_glue(wl); | ||
177 | struct spi_transfer t[1]; | 185 | struct spi_transfer t[1]; |
178 | struct spi_message m; | 186 | struct spi_message m; |
179 | u32 *busy_buf; | 187 | u32 *busy_buf; |
@@ -194,7 +202,7 @@ static int wl1271_spi_read_busy(struct wl1271 *wl) | |||
194 | t[0].len = sizeof(u32); | 202 | t[0].len = sizeof(u32); |
195 | t[0].cs_change = true; | 203 | t[0].cs_change = true; |
196 | spi_message_add_tail(&t[0], &m); | 204 | spi_message_add_tail(&t[0], &m); |
197 | spi_sync(wl_to_spi(wl), &m); | 205 | spi_sync(to_spi_device(glue->dev), &m); |
198 | 206 | ||
199 | if (*busy_buf & 0x1) | 207 | if (*busy_buf & 0x1) |
200 | return 0; | 208 | return 0; |
@@ -208,6 +216,7 @@ static int wl1271_spi_read_busy(struct wl1271 *wl) | |||
208 | static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | 216 | static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, |
209 | size_t len, bool fixed) | 217 | size_t len, bool fixed) |
210 | { | 218 | { |
219 | struct wl12xx_spi_glue *glue = wl_to_glue(wl); | ||
211 | struct spi_transfer t[2]; | 220 | struct spi_transfer t[2]; |
212 | struct spi_message m; | 221 | struct spi_message m; |
213 | u32 *busy_buf; | 222 | u32 *busy_buf; |
@@ -243,7 +252,7 @@ static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
243 | t[1].cs_change = true; | 252 | t[1].cs_change = true; |
244 | spi_message_add_tail(&t[1], &m); | 253 | spi_message_add_tail(&t[1], &m); |
245 | 254 | ||
246 | spi_sync(wl_to_spi(wl), &m); | 255 | spi_sync(to_spi_device(glue->dev), &m); |
247 | 256 | ||
248 | if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && | 257 | if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && |
249 | wl1271_spi_read_busy(wl)) { | 258 | wl1271_spi_read_busy(wl)) { |
@@ -259,7 +268,7 @@ static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
259 | t[0].cs_change = true; | 268 | t[0].cs_change = true; |
260 | spi_message_add_tail(&t[0], &m); | 269 | spi_message_add_tail(&t[0], &m); |
261 | 270 | ||
262 | spi_sync(wl_to_spi(wl), &m); | 271 | spi_sync(to_spi_device(glue->dev), &m); |
263 | 272 | ||
264 | wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); | 273 | wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); |
265 | wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len); | 274 | wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len); |
@@ -274,6 +283,7 @@ static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
274 | static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | 283 | static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, |
275 | size_t len, bool fixed) | 284 | size_t len, bool fixed) |
276 | { | 285 | { |
286 | struct wl12xx_spi_glue *glue = wl_to_glue(wl); | ||
277 | struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; | 287 | struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; |
278 | struct spi_message m; | 288 | struct spi_message m; |
279 | u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; | 289 | u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; |
@@ -318,7 +328,7 @@ static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
318 | cmd++; | 328 | cmd++; |
319 | } | 329 | } |
320 | 330 | ||
321 | spi_sync(wl_to_spi(wl), &m); | 331 | spi_sync(to_spi_device(glue->dev), &m); |
322 | } | 332 | } |
323 | 333 | ||
324 | static irqreturn_t wl1271_hardirq(int irq, void *cookie) | 334 | static irqreturn_t wl1271_hardirq(int irq, void *cookie) |
@@ -362,11 +372,12 @@ static struct wl1271_if_operations spi_ops = { | |||
362 | 372 | ||
363 | static int __devinit wl1271_probe(struct spi_device *spi) | 373 | static int __devinit wl1271_probe(struct spi_device *spi) |
364 | { | 374 | { |
375 | struct wl12xx_spi_glue *glue; | ||
365 | struct wl12xx_platform_data *pdata; | 376 | struct wl12xx_platform_data *pdata; |
366 | struct ieee80211_hw *hw; | 377 | struct ieee80211_hw *hw; |
367 | struct wl1271 *wl; | 378 | struct wl1271 *wl; |
368 | unsigned long irqflags; | 379 | unsigned long irqflags; |
369 | int ret; | 380 | int ret = -ENOMEM; |
370 | 381 | ||
371 | pdata = spi->dev.platform_data; | 382 | pdata = spi->dev.platform_data; |
372 | if (!pdata) { | 383 | if (!pdata) { |
@@ -374,14 +385,25 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
374 | return -ENODEV; | 385 | return -ENODEV; |
375 | } | 386 | } |
376 | 387 | ||
388 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
389 | if (!glue) { | ||
390 | wl1271_error("can't allocate glue"); | ||
391 | goto out; | ||
392 | } | ||
393 | |||
377 | hw = wl1271_alloc_hw(); | 394 | hw = wl1271_alloc_hw(); |
378 | if (IS_ERR(hw)) | 395 | if (IS_ERR(hw)) { |
379 | return PTR_ERR(hw); | 396 | ret = PTR_ERR(hw); |
397 | goto out_free_glue; | ||
398 | } | ||
380 | 399 | ||
381 | wl = hw->priv; | 400 | wl = hw->priv; |
382 | 401 | ||
383 | dev_set_drvdata(&spi->dev, wl); | 402 | glue->dev = &spi->dev; |
384 | wl->if_priv = spi; | 403 | glue->wl = wl; |
404 | |||
405 | spi_set_drvdata(spi, glue); | ||
406 | wl->if_priv = glue; | ||
385 | 407 | ||
386 | wl->if_ops = &spi_ops; | 408 | wl->if_ops = &spi_ops; |
387 | 409 | ||
@@ -392,14 +414,14 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
392 | ret = spi_setup(spi); | 414 | ret = spi_setup(spi); |
393 | if (ret < 0) { | 415 | if (ret < 0) { |
394 | wl1271_error("spi_setup failed"); | 416 | wl1271_error("spi_setup failed"); |
395 | goto out_free; | 417 | goto out_free_hw; |
396 | } | 418 | } |
397 | 419 | ||
398 | wl->set_power = pdata->set_power; | 420 | wl->set_power = pdata->set_power; |
399 | if (!wl->set_power) { | 421 | if (!wl->set_power) { |
400 | wl1271_error("set power function missing in platform data"); | 422 | wl1271_error("set power function missing in platform data"); |
401 | ret = -ENODEV; | 423 | ret = -ENODEV; |
402 | goto out_free; | 424 | goto out_free_hw; |
403 | } | 425 | } |
404 | 426 | ||
405 | wl->ref_clock = pdata->board_ref_clock; | 427 | wl->ref_clock = pdata->board_ref_clock; |
@@ -415,7 +437,7 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
415 | if (wl->irq < 0) { | 437 | if (wl->irq < 0) { |
416 | wl1271_error("irq missing in platform data"); | 438 | wl1271_error("irq missing in platform data"); |
417 | ret = -ENODEV; | 439 | ret = -ENODEV; |
418 | goto out_free; | 440 | goto out_free_hw; |
419 | } | 441 | } |
420 | 442 | ||
421 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, | 443 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, |
@@ -423,7 +445,7 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
423 | DRIVER_NAME, wl); | 445 | DRIVER_NAME, wl); |
424 | if (ret < 0) { | 446 | if (ret < 0) { |
425 | wl1271_error("request_irq() failed: %d", ret); | 447 | wl1271_error("request_irq() failed: %d", ret); |
426 | goto out_free; | 448 | goto out_free_hw; |
427 | } | 449 | } |
428 | 450 | ||
429 | disable_irq(wl->irq); | 451 | disable_irq(wl->irq); |
@@ -438,22 +460,27 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
438 | 460 | ||
439 | return 0; | 461 | return 0; |
440 | 462 | ||
441 | out_irq: | 463 | out_irq: |
442 | free_irq(wl->irq, wl); | 464 | free_irq(wl->irq, wl); |
443 | 465 | ||
444 | out_free: | 466 | out_free_hw: |
445 | wl1271_free_hw(wl); | 467 | wl1271_free_hw(wl); |
446 | 468 | ||
469 | out_free_glue: | ||
470 | kfree(glue); | ||
471 | out: | ||
447 | return ret; | 472 | return ret; |
448 | } | 473 | } |
449 | 474 | ||
450 | static int __devexit wl1271_remove(struct spi_device *spi) | 475 | static int __devexit wl1271_remove(struct spi_device *spi) |
451 | { | 476 | { |
452 | struct wl1271 *wl = dev_get_drvdata(&spi->dev); | 477 | struct wl12xx_spi_glue *glue = spi_get_drvdata(spi); |
478 | struct wl1271 *wl = glue->wl; | ||
453 | 479 | ||
454 | wl1271_unregister_hw(wl); | 480 | wl1271_unregister_hw(wl); |
455 | free_irq(wl->irq, wl); | 481 | free_irq(wl->irq, wl); |
456 | wl1271_free_hw(wl); | 482 | wl1271_free_hw(wl); |
483 | kfree(glue); | ||
457 | 484 | ||
458 | return 0; | 485 | return 0; |
459 | } | 486 | } |