aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax/i2400m/sdio.c
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2009-09-16 21:23:27 -0400
committerInaky Perez-Gonzalez <inaky@linux.intel.com>2009-10-19 02:56:08 -0400
commit0856ccf29dfbaf957e4be80dd3eb88d97810b633 (patch)
treea33cf96b010ce3814747b67eb60743554af2070f /drivers/net/wimax/i2400m/sdio.c
parentc2315b4ea9ac9c3f8caf03c3511d86fabe4a5fcd (diff)
wimax/i2400m: introduce i2400m->bus_setup/release
The SDIO subdriver of the i2400m requires certain steps to be done before we do any acces to the device, even for doing firmware upload. This lead to a few ugly hacks, which basically involve doing those steps in probe() before calling i2400m_setup() and undoing them in disconnect() after claling i2400m_release(); but then, much of those steps have to be repeated when resetting the device, suspending, etc (in upcoming pre/post reset support). Thus, a new pair of optional, bus-specific calls i2400m->bus_{setup/release} are introduced. These are used to setup basic infrastructure needed to load firmware onto the device. This commit also updates the SDIO subdriver to use said calls. Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'drivers/net/wimax/i2400m/sdio.c')
-rw-r--r--drivers/net/wimax/i2400m/sdio.c100
1 files changed, 64 insertions, 36 deletions
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index de158ee0c32c..6e39665ecd89 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -165,6 +165,66 @@ function_enabled:
165 165
166 166
167/* 167/*
168 * Setup minimal device communication infrastructure needed to at
169 * least be able to update the firmware.
170 */
171static
172int i2400ms_bus_setup(struct i2400m *i2400m)
173{
174 int result;
175 struct i2400ms *i2400ms =
176 container_of(i2400m, struct i2400ms, i2400m);
177 struct device *dev = i2400m_dev(i2400m);
178 struct sdio_func *func = i2400ms->func;
179
180 sdio_claim_host(func);
181 result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
182 sdio_release_host(func);
183 if (result < 0) {
184 dev_err(dev, "Failed to set block size: %d\n", result);
185 goto error_set_blk_size;
186 }
187
188 result = i2400ms_enable_function(func, 1);
189 if (result < 0) {
190 dev_err(dev, "Cannot enable SDIO function: %d\n", result);
191 goto error_func_enable;
192 }
193
194 result = i2400ms_rx_setup(i2400ms);
195 if (result < 0)
196 goto error_rx_setup;
197 return 0;
198
199error_rx_setup:
200 sdio_claim_host(func);
201 sdio_disable_func(func);
202 sdio_release_host(func);
203error_func_enable:
204error_set_blk_size:
205 return result;
206}
207
208
209/*
210 * Tear down minimal device communication infrastructure needed to at
211 * least be able to update the firmware.
212 */
213static
214void i2400ms_bus_release(struct i2400m *i2400m)
215{
216 struct i2400ms *i2400ms =
217 container_of(i2400m, struct i2400ms, i2400m);
218 struct sdio_func *func = i2400ms->func;
219
220 i2400ms_rx_release(i2400ms);
221 sdio_claim_host(func);
222 sdio_disable_func(func);
223 sdio_release_host(func);
224}
225
226
227/*
168 * Setup driver resources needed to communicate with the device 228 * Setup driver resources needed to communicate with the device
169 * 229 *
170 * The fw needs some time to settle, and it was just uploaded, 230 * The fw needs some time to settle, and it was just uploaded,
@@ -315,17 +375,12 @@ do_bus_reset:
315 if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED) 375 if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
316 netif_tx_disable(i2400m->wimax_dev.net_dev); 376 netif_tx_disable(i2400m->wimax_dev.net_dev);
317 377
318 i2400ms_rx_release(i2400ms); 378 i2400ms_bus_release(i2400m);
319 sdio_claim_host(i2400ms->func);
320 sdio_disable_func(i2400ms->func);
321 sdio_release_host(i2400ms->func);
322 379
323 /* Wait for the device to settle */ 380 /* Wait for the device to settle */
324 msleep(40); 381 msleep(40);
325 382
326 result = i2400ms_enable_function(i2400ms->func, 0); 383 result = i2400ms_bus_setup(i2400m);
327 if (result >= 0)
328 i2400ms_rx_setup(i2400ms);
329 } else 384 } else
330 BUG(); 385 BUG();
331 if (result < 0 && rt != I2400M_RT_BUS) { 386 if (result < 0 && rt != I2400M_RT_BUS) {
@@ -449,8 +504,10 @@ int i2400ms_probe(struct sdio_func *func,
449 504
450 i2400m->bus_tx_block_size = I2400MS_BLK_SIZE; 505 i2400m->bus_tx_block_size = I2400MS_BLK_SIZE;
451 i2400m->bus_pl_size_max = I2400MS_PL_SIZE_MAX; 506 i2400m->bus_pl_size_max = I2400MS_PL_SIZE_MAX;
507 i2400m->bus_setup = i2400ms_bus_setup;
452 i2400m->bus_dev_start = i2400ms_bus_dev_start; 508 i2400m->bus_dev_start = i2400ms_bus_dev_start;
453 i2400m->bus_dev_stop = i2400ms_bus_dev_stop; 509 i2400m->bus_dev_stop = i2400ms_bus_dev_stop;
510 i2400m->bus_release = i2400ms_bus_release;
454 i2400m->bus_tx_kick = i2400ms_bus_tx_kick; 511 i2400m->bus_tx_kick = i2400ms_bus_tx_kick;
455 i2400m->bus_reset = i2400ms_bus_reset; 512 i2400m->bus_reset = i2400ms_bus_reset;
456 /* The iwmc3200-wimax sometimes requires the driver to try 513 /* The iwmc3200-wimax sometimes requires the driver to try
@@ -462,20 +519,6 @@ int i2400ms_probe(struct sdio_func *func,
462 i2400m->bus_bm_mac_addr_impaired = 1; 519 i2400m->bus_bm_mac_addr_impaired = 1;
463 i2400m->bus_bm_pokes_table = &i2400ms_pokes[0]; 520 i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
464 521
465 sdio_claim_host(func);
466 result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
467 sdio_release_host(func);
468 if (result < 0) {
469 dev_err(dev, "Failed to set block size: %d\n", result);
470 goto error_set_blk_size;
471 }
472
473 result = i2400ms_enable_function(i2400ms->func, 1);
474 if (result < 0) {
475 dev_err(dev, "Cannot enable SDIO function: %d\n", result);
476 goto error_func_enable;
477 }
478
479 /* 522 /*
480 * Before we are enabling the device interrupt register, make 523 * Before we are enabling the device interrupt register, make
481 * sure the buffer used during bootmode operation is setup so 524 * sure the buffer used during bootmode operation is setup so
@@ -488,10 +531,6 @@ int i2400ms_probe(struct sdio_func *func,
488 goto error_bootmode_buf_setup; 531 goto error_bootmode_buf_setup;
489 } 532 }
490 533
491 result = i2400ms_rx_setup(i2400ms);
492 if (result < 0)
493 goto error_rx_setup;
494
495 result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT); 534 result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT);
496 if (result < 0) { 535 if (result < 0) {
497 dev_err(dev, "cannot setup device: %d\n", result); 536 dev_err(dev, "cannot setup device: %d\n", result);
@@ -509,15 +548,8 @@ int i2400ms_probe(struct sdio_func *func,
509error_debugfs_add: 548error_debugfs_add:
510 i2400m_release(i2400m); 549 i2400m_release(i2400m);
511error_setup: 550error_setup:
512 i2400ms_rx_release(i2400ms);
513error_rx_setup:
514 i2400m_bm_buf_free(i2400m); 551 i2400m_bm_buf_free(i2400m);
515error_bootmode_buf_setup: 552error_bootmode_buf_setup:
516 sdio_claim_host(func);
517 sdio_disable_func(func);
518 sdio_release_host(func);
519error_func_enable:
520error_set_blk_size:
521 sdio_set_drvdata(func, NULL); 553 sdio_set_drvdata(func, NULL);
522 free_netdev(net_dev); 554 free_netdev(net_dev);
523error_alloc_netdev: 555error_alloc_netdev:
@@ -535,12 +567,8 @@ void i2400ms_remove(struct sdio_func *func)
535 567
536 d_fnstart(3, dev, "SDIO func %p\n", func); 568 d_fnstart(3, dev, "SDIO func %p\n", func);
537 debugfs_remove_recursive(i2400ms->debugfs_dentry); 569 debugfs_remove_recursive(i2400ms->debugfs_dentry);
538 i2400ms_rx_release(i2400ms);
539 i2400m_release(i2400m); 570 i2400m_release(i2400m);
540 sdio_set_drvdata(func, NULL); 571 sdio_set_drvdata(func, NULL);
541 sdio_claim_host(func);
542 sdio_disable_func(func);
543 sdio_release_host(func);
544 free_netdev(net_dev); 572 free_netdev(net_dev);
545 d_fnend(3, dev, "SDIO func %p\n", func); 573 d_fnend(3, dev, "SDIO func %p\n", func);
546} 574}