staging: csr: remove oska submodule
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / csr / sdio_emb.c
1 /*
2  * ---------------------------------------------------------------------------
3  *
4  * FILE: sdio_emb.c
5  *
6  * PURPOSE: Driver instantiation and deletion for SDIO on Linux.
7  *
8  *      This file brings together the SDIO bus interface, the UniFi
9  *      driver core and the Linux net_device stack.
10  *
11  * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
12  *
13  * Refer to LICENSE.txt included with this source code for details on
14  * the license terms.
15  *
16  * ---------------------------------------------------------------------------
17  */
18 #include <linux/kmod.h>
19 #include <linux/init.h>
20 #include <linux/suspend.h>
21 #include "csr_wifi_hip_unifi.h"
22 #include "unifi_priv.h"
23
24 #include "sdioemb/sdio_api.h"
25
26 /* The function driver context, i.e the UniFi Driver */
27 static CsrSdioFunctionDriver *sdio_func_drv;
28
29 #ifdef CONFIG_PM
30 static int uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr);
31 #endif
32
33 /* The Android wakelock is here for completeness. Typically the MMC driver is used
34  * instead of sdioemb, but sdioemb may be used for CSPI.
35  */
36 #ifdef ANDROID_BUILD
37 struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
38 #endif
39
40 /* sdioemb driver uses POSIX error codes */
41 static CsrResult
42 ConvertSdioToCsrSdioResult(int r)
43 {
44     CsrResult csrResult = CSR_RESULT_FAILURE;
45
46     switch (r) {
47         case 0:
48             csrResult = CSR_RESULT_SUCCESS;
49             break;
50         case -EIO:
51             csrResult = CSR_SDIO_RESULT_CRC_ERROR;
52             break;
53             /* Timeout errors */
54         case -ETIMEDOUT:
55         case -EBUSY:
56             csrResult = CSR_SDIO_RESULT_TIMEOUT;
57             break;
58         case -ENODEV:
59         case -ENOMEDIUM:
60             csrResult = CSR_SDIO_RESULT_NO_DEVICE;
61             break;
62         case -EINVAL:
63             csrResult = CSR_SDIO_RESULT_INVALID_VALUE;
64             break;
65         case -ENOMEM:
66         case -ENOSYS:
67         case -EILSEQ:
68         case -ERANGE:
69         case -ENXIO:
70             csrResult = CSR_RESULT_FAILURE;
71             break;
72         default:
73             unifi_warning(NULL, "Unrecognised SDIO error code: %d\n", r);
74             break;
75     }
76
77     return csrResult;
78 }
79
80
81 CsrResult
82 CsrSdioRead8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data)
83 {
84     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
85     int err;
86     err = sdioemb_read8(fdev, address, data);
87     if (err) {
88         return ConvertSdioToCsrSdioResult(err);
89     }
90     return CSR_RESULT_SUCCESS;
91 } /* CsrSdioRead8() */
92
93 CsrResult
94 CsrSdioWrite8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data)
95 {
96     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
97     int err;
98     err = sdioemb_write8(fdev, address, data);
99     if (err) {
100         return ConvertSdioToCsrSdioResult(err);
101     }
102     return CSR_RESULT_SUCCESS;
103 } /* CsrSdioWrite8() */
104
105 CsrResult
106 CsrSdioRead16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data)
107 {
108     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
109     int r;
110
111     r = sdioemb_read16(fdev, address, data);
112     if (r) {
113         return ConvertSdioToCsrSdioResult(r);
114     }
115
116     return CSR_RESULT_SUCCESS;
117 } /* CsrSdioRead16() */
118
119 CsrResult
120 CsrSdioWrite16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data)
121 {
122     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
123     int r;
124
125     r = sdioemb_write16(fdev, address, data);
126     if (r) {
127         return ConvertSdioToCsrSdioResult(r);
128     }
129
130     return CSR_RESULT_SUCCESS;
131 } /* CsrSdioWrite16() */
132
133
134 CsrResult
135 CsrSdioF0Read8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data)
136 {
137     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
138     int err;
139     err = sdioemb_f0_read8(fdev, address, data);
140     if (err) {
141         return ConvertSdioToCsrSdioResult(err);
142     }
143     return CSR_RESULT_SUCCESS;
144 } /* CsrSdioF0Read8() */
145
146
147 CsrResult
148 CsrSdioF0Write8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data)
149 {
150     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
151     int err;
152     err = sdioemb_f0_write8(fdev, address, data);
153     if (err) {
154         return ConvertSdioToCsrSdioResult(err);
155     }
156     return CSR_RESULT_SUCCESS;
157 } /* CsrSdioF0Write8() */
158
159 CsrResult
160 CsrSdioRead(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length)
161 {
162     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
163     int err;
164     err = sdioemb_read(fdev, address, data, length);
165     if (err) {
166         return ConvertSdioToCsrSdioResult(err);
167     }
168     return CSR_RESULT_SUCCESS;
169 } /* CsrSdioRead() */
170
171 CsrResult
172 CsrSdioWrite(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length)
173 {
174     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
175     int err;
176     err = sdioemb_write(fdev, address, data, length);
177     if (err) {
178         return ConvertSdioToCsrSdioResult(err);
179     }
180     return CSR_RESULT_SUCCESS;
181 } /* CsrSdioWrite() */
182
183
184 CsrResult
185 CsrSdioBlockSizeSet(CsrSdioFunction *function, CsrUint16 blockSize)
186 {
187     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
188     int r = 0;
189
190     /* Module parameter overrides */
191     if (sdio_block_size > -1) {
192         blockSize = sdio_block_size;
193     }
194
195     unifi_trace(NULL, UDBG1, "Set SDIO function block size to %d\n",
196             blockSize);
197
198     r = sdioemb_set_block_size(fdev, blockSize);
199     if (r) {
200         unifi_error(NULL, "Error %d setting block size\n", r);
201     }
202
203     /* Determine the achieved block size to report to the core */
204     function->blockSize = fdev->blocksize;
205
206     return ConvertSdioToCsrSdioResult(r);
207 } /* CsrSdioBlockSizeSet() */
208
209
210 /*
211  * ---------------------------------------------------------------------------
212  *  CsrSdioMaxBusClockFrequencySet
213  *
214  *      Set the maximum SDIO bus clock speed to use.
215  *
216  *  Arguments:
217  *      sdio            SDIO context pointer
218  *      maxFrequency         maximum clock speed in Hz
219  *
220  *  Returns:
221  *      an error code.
222  * ---------------------------------------------------------------------------
223  */
224 CsrResult
225 CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, CsrUint32 maxFrequency)
226 {
227     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
228     CsrUint32 max_khz = maxFrequency/1000;
229
230     if (!max_khz || max_khz > sdio_clock) {
231         max_khz = sdio_clock;
232     }
233     unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", max_khz);
234     sdioemb_set_max_bus_freq(fdev, 1000 * max_khz);
235
236     return CSR_RESULT_SUCCESS;
237 } /* CsrSdioMaxBusClockFrequencySet() */
238
239
240 /*
241  * ---------------------------------------------------------------------------
242  *  CsrSdioInterruptEnable
243  *  CsrSdioInterruptDisable
244  *
245  *      Enable or disable the SDIO interrupt.
246  *
247  *  Arguments:
248  *      sdio            SDIO context pointer
249  *
250  *  Returns:
251  *      Zero on success or a UniFi driver error code.
252  * ---------------------------------------------------------------------------
253  */
254 CsrResult
255 CsrSdioInterruptEnable(CsrSdioFunction *function)
256 {
257     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
258     int r;
259
260     r = sdioemb_interrupt_enable(fdev);
261     if (r) {
262         return ConvertSdioToCsrSdioResult(r);
263     }
264
265     return CSR_RESULT_SUCCESS;
266 } /* CsrSdioInterruptEnable() */
267
268 CsrResult
269 CsrSdioInterruptDisable(CsrSdioFunction *function)
270 {
271     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
272     int r;
273
274     r = sdioemb_interrupt_disable(fdev);
275     if (r) {
276         return ConvertSdioToCsrSdioResult(r);
277     }
278
279     return CSR_RESULT_SUCCESS;
280 } /* CsrSdioInterruptDisable() */
281
282
283 /*
284  * ---------------------------------------------------------------------------
285  *  CsrSdioInterruptAcknowledge
286  *
287  *      Acknowledge an SDIO interrupt.
288  *
289  *  Arguments:
290  *      sdio            SDIO context pointer
291  *
292  *  Returns:
293  *      Zero on success or a UniFi driver error code.
294  * ---------------------------------------------------------------------------
295  */
296 void CsrSdioInterruptAcknowledge(CsrSdioFunction *function)
297 {
298     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
299
300     sdioemb_interrupt_acknowledge(fdev);
301 } /* CsrSdioInterruptAcknowledge() */
302
303
304 /*
305  * ---------------------------------------------------------------------------
306  *  CsrSdioFunctionEnable
307  *
308  *      Enable i/o on this function.
309  *
310  *  Arguments:
311  *      sdio            SDIO context pointer
312  *
313  * Returns:
314  *      UniFi driver error code.
315  * ---------------------------------------------------------------------------
316  */
317 CsrResult
318 CsrSdioFunctionEnable(CsrSdioFunction *function)
319 {
320     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
321     int r;
322
323     /* Enable UniFi function (the 802.11 part). */
324     r = sdioemb_enable_function(fdev);
325     if (r) {
326         unifi_error(NULL, "Failed to enable SDIO function %d\n", fdev->function);
327         return ConvertSdioToCsrSdioResult(r);
328     }
329     return CSR_RESULT_SUCCESS;
330 } /* CsrSdioFunctionEnable() */
331
332
333 /*
334  * ---------------------------------------------------------------------------
335  *  CsrSdioFunctionDisable
336  *
337  *      Disable i/o on this function.
338  *
339  *  Arguments:
340  *      sdio            SDIO context pointer
341  *
342  * Returns:
343  *      UniFi driver error code.
344  * ---------------------------------------------------------------------------
345  */
346 CsrResult
347 CsrSdioFunctionDisable(CsrSdioFunction *function)
348 {
349     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
350     int r;
351
352     /* Disable UniFi function (the 802.11 part). */
353     r = sdioemb_disable_function(fdev);
354     if (r) {
355         unifi_error(NULL, "Failed to disable SDIO function %d\n", fdev->function);
356         return ConvertSdioToCsrSdioResult(r);
357     }
358     return CSR_RESULT_SUCCESS;
359 } /* CsrSdioFunctionDisable() */
360
361
362 /*
363  * ---------------------------------------------------------------------------
364  *  CsrSdioFunctionActive
365  *
366  *      No-op as the bus goes to an active state at the start of every
367  *      command.
368  *
369  *  Arguments:
370  *      sdio            SDIO context pointer
371  * ---------------------------------------------------------------------------
372  */
373 void
374 CsrSdioFunctionActive(CsrSdioFunction *function)
375 {
376 } /* CsrSdioFunctionActive() */
377
378 /*
379  * ---------------------------------------------------------------------------
380  *  CsrSdioFunctionIdle
381  *
382  *      Set the function as idle.
383  *
384  *  Arguments:
385  *      sdio            SDIO context pointer
386  * ---------------------------------------------------------------------------
387  */
388 void
389 CsrSdioFunctionIdle(CsrSdioFunction *function)
390 {
391     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
392
393     sdioemb_idle_function(fdev);
394 } /* CsrSdioFunctionIdle() */
395
396
397 CsrResult
398 CsrSdioPowerOn(CsrSdioFunction *function)
399 {
400     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
401
402     if (disable_power_control != 1) {
403         sdioemb_power_on(fdev);
404     }
405
406     return CSR_RESULT_SUCCESS;
407 } /* CsrSdioPowerOn() */
408
409 void
410 CsrSdioPowerOff(CsrSdioFunction *function)
411 {
412     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
413     if (disable_power_control != 1) {
414         sdioemb_power_off(fdev);
415     }
416 } /* CsrSdioPowerOff() */
417
418
419 /*
420  * ---------------------------------------------------------------------------
421  *  CsrSdioHardReset
422  *
423  *      Hard Resets UniFi is possible.
424  *
425  *  Arguments:
426  *      sdio            SDIO context pointer
427  *
428  * Returns:
429  *      1       if the SDIO driver is not capable of doing a hard reset.
430  *      0       if a hard reset was successfully performed.
431  *      -CSR_EIO if an I/O error occured while re-initializing the card.
432  *              This is a fatal, non-recoverable error.
433  *      -CSR_ENODEV if the card is no longer present.
434  * ---------------------------------------------------------------------------
435  */
436 CsrResult
437 CsrSdioHardReset(CsrSdioFunction *function)
438 {
439     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
440     int r;
441
442     /* Hard reset can be disabled by a module parameter */
443     r = 1;
444     if (disable_hw_reset != 1) {
445         r = sdioemb_hard_reset(fdev); /* may return 1 if can't reset */
446         if (r < 0) {
447             return ConvertSdioToCsrSdioResult(r);   /* fatal error */
448         }
449     }
450
451     /* Set the SDIO bus width after a hard reset */
452     if (buswidth == 1) {
453         unifi_info(NULL, "Setting SDIO bus width to 1\n");
454         sdioemb_set_bus_width(fdev, buswidth);
455     } else if (buswidth == 4) {
456         unifi_info(NULL, "Setting SDIO bus width to 4\n");
457         sdioemb_set_bus_width(fdev, buswidth);
458     }
459
460     if(r == 1)
461     {
462         return CSR_SDIO_RESULT_NOT_RESET;
463     }
464
465     return ConvertSdioToCsrSdioResult(r);
466
467 } /* CsrSdioHardReset() */
468
469
470 int csr_sdio_linux_remove_irq(CsrSdioFunction *function)
471 {
472     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
473
474     return sdioemb_interrupt_disable(fdev);
475 }
476
477 int csr_sdio_linux_install_irq(CsrSdioFunction *function)
478 {
479     struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
480
481     return sdioemb_interrupt_enable(fdev);
482 }
483
484
485 /*
486  * ---------------------------------------------------------------------------
487  *  uf_glue_sdio_int_handler
488  *      Card interrupt callback.
489  *
490  * Arguments:
491  *      fdev            SDIO context pointer
492  *
493  * Returns:
494  *      None.
495  * ---------------------------------------------------------------------------
496  */
497 static void
498 uf_glue_sdio_int_handler(struct sdioemb_dev *fdev)
499 {
500     CsrSdioFunction *sdio_ctx = fdev->drv_data;
501     CsrSdioInterruptDsrCallback func_dsr_callback;
502
503     /* If the function driver has registered a handler, call it */
504     if (sdio_func_drv && sdio_func_drv->intr) {
505         /* The function driver may return a DSR. */
506         func_dsr_callback = sdio_func_drv->intr(sdio_ctx);
507         /* If it did return a DSR handle, call it */
508         if (func_dsr_callback) {
509             func_dsr_callback(sdio_ctx);
510         }
511     }
512 }
513
514 #ifdef CONFIG_PM
515
516 /*
517  * Power Management notifier
518  */
519 struct uf_sdio_emb_pm_notifier
520 {
521     struct list_head list;
522
523     CsrSdioFunction *sdio_ctx;
524     struct notifier_block pm_notifier;
525 };
526
527 /* PM notifier list head */
528 static struct uf_sdio_emb_pm_notifier uf_sdio_emb_pm_notifiers = {
529     .sdio_ctx = NULL,
530 };
531
532 /*
533  * ---------------------------------------------------------------------------
534  * uf_sdio_emb_register_pm_notifier
535  * uf_sdio_emb_unregister_pm_notifier
536  *
537  *      Register/unregister for power management events. A list is used to
538  *      allow multiple card instances to be supported.
539  *
540  *  Arguments:
541  *      sdio_ctx - CSR SDIO context to associate PM notifier to
542  *
543  *  Returns:
544  *      Register function returns NULL on error
545  * ---------------------------------------------------------------------------
546  */
547 static struct uf_sdio_emb_pm_notifier *
548 uf_sdio_emb_register_pm_notifier(CsrSdioFunction *sdio_ctx)
549 {
550     /* Allocate notifier context for this card instance */
551     struct uf_sdio_emb_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_emb_pm_notifier), GFP_KERNEL);
552
553     if (notifier_ctx)
554     {
555         notifier_ctx->sdio_ctx = sdio_ctx;
556         notifier_ctx->pm_notifier.notifier_call = uf_sdio_emb_power_event;
557
558         list_add(&notifier_ctx->list, &uf_sdio_emb_pm_notifiers.list);
559
560         if (register_pm_notifier(&notifier_ctx->pm_notifier)) {
561             printk(KERN_ERR "unifi: register_pm_notifier failed\n");
562         }
563     }
564
565     return notifier_ctx;
566 }
567
568 static void
569 uf_sdio_emb_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
570 {
571     struct uf_sdio_emb_pm_notifier *notifier_ctx;
572     struct list_head *node, *q;
573
574     list_for_each_safe(node, q, &uf_sdio_emb_pm_notifiers.list) {
575         notifier_ctx = list_entry(node, struct uf_sdio_emb_pm_notifier, list);
576
577         /* If it matches, unregister and free the notifier context */
578         if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
579         {
580             if (unregister_pm_notifier(&notifier_ctx->pm_notifier)) {
581                 printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
582             }
583
584             /* Remove from list */
585             notifier_ctx->sdio_ctx = NULL;
586             list_del(node);
587             kfree(notifier_ctx);
588         }
589     }
590 }
591
592 /*
593  * ---------------------------------------------------------------------------
594  * uf_sdio_emb_power_event
595  *
596  *      Handler for power management events.
597  *
598  *      We need to handle suspend/resume events while the userspace is unsuspended
599  *      to allow the SME to run its suspend/resume state machines.
600  *
601  *  Arguments:
602  *      event   event ID
603  *
604  *  Returns:
605  *      Status of the event handling
606  * ---------------------------------------------------------------------------
607  */
608 static int
609 uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr)
610 {
611     struct uf_sdio_emb_pm_notifier *notifier_ctx = container_of(this,
612                                                                 struct uf_sdio_emb_pm_notifier,
613                                                                 pm_notifier);
614
615     /* Call the CSR SDIO function driver's suspend/resume method
616      * while the userspace is unsuspended.
617      */
618     switch (event) {
619         case PM_POST_HIBERNATION:
620         case PM_POST_SUSPEND:
621             printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
622             if (sdio_func_drv && sdio_func_drv->resume) {
623                 sdio_func_drv->resume(notifier_ctx->sdio_ctx);
624             }
625             break;
626
627         case PM_HIBERNATION_PREPARE:
628         case PM_SUSPEND_PREPARE:
629             printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
630             if (sdio_func_drv && sdio_func_drv->suspend) {
631                 sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
632             }
633             break;
634     }
635     return NOTIFY_DONE;
636 }
637
638 #endif /* CONFIG_PM */
639
640 /*
641  * ---------------------------------------------------------------------------
642  *  uf_glue_sdio_probe
643  *
644  *      Card insert callback.
645  *
646  * Arguments:
647  *      fdev            SDIO context pointer
648  *
649  * Returns:
650  *      UniFi driver error code.
651  * ---------------------------------------------------------------------------
652  */
653 static int
654 uf_glue_sdio_probe(struct sdioemb_dev *fdev)
655 {
656     CsrSdioFunction *sdio_ctx;
657
658     unifi_info(NULL, "UniFi card inserted\n");
659
660     /* Allocate context and private in one lump */
661     sdio_ctx = (CsrSdioFunction *)kmalloc(sizeof(CsrSdioFunction),
662                                           GFP_KERNEL);
663     if (sdio_ctx == NULL) {
664         return -ENOMEM;
665     }
666
667
668     sdio_ctx->sdioId.manfId = fdev->vendor_id;
669     sdio_ctx->sdioId.cardId = fdev->device_id;
670     sdio_ctx->sdioId.sdioFunction = fdev->function;
671     sdio_ctx->sdioId.sdioInterface = 0;
672     sdio_ctx->blockSize = fdev->blocksize;
673     sdio_ctx->priv = (void *)fdev;
674     sdio_ctx->features = 0;
675
676     /* Module parameter enables byte mode */
677     if (sdio_byte_mode) {
678         sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE;
679     }
680
681     /* Set up pointer to func_priv in middle of lump */
682     fdev->drv_data = sdio_ctx;
683
684     /* Always override default SDIO bus clock */
685     unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock);
686     sdioemb_set_max_bus_freq(fdev, 1000 * sdio_clock);
687
688 #ifdef CONFIG_PM
689     /* Register to get PM events */
690     if (uf_sdio_emb_register_pm_notifier(sdio_ctx) == NULL) {
691         unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
692     }
693 #endif
694
695     /* Call the main UniFi driver inserted handler */
696     if (sdio_func_drv && sdio_func_drv->inserted) {
697         uf_add_os_device(fdev->slot_id, fdev->os_device);
698         sdio_func_drv->inserted(sdio_ctx);
699     }
700
701 #ifdef ANDROID_BUILD
702     /* Take the wakelock */
703     unifi_trace(NULL, UDBG1, "emb probe: take wake lock\n");
704     wake_lock(&unifi_sdio_wake_lock);
705 #endif
706
707     return 0;
708 } /* uf_glue_sdio_probe() */
709
710
711
712 /*
713  * ---------------------------------------------------------------------------
714  *  uf_sdio_remove
715  *
716  *      Card removal callback.
717  *
718  * Arguments:
719  *      fdev            SDIO device
720  *
721  * Returns:
722  *      UniFi driver error code.
723  * ---------------------------------------------------------------------------
724  */
725 static void
726 uf_sdio_remove(struct sdioemb_dev *fdev)
727 {
728     CsrSdioFunction *sdio_ctx = fdev->drv_data;
729
730     unifi_info(NULL, "UniFi card removed\n");
731
732     /* Clean up the SDIO function driver */
733     if (sdio_func_drv && sdio_func_drv->removed) {
734         sdio_func_drv->removed(sdio_ctx);
735     }
736
737 #ifdef CONFIG_PM
738     /* Unregister for PM events */
739     uf_sdio_emb_unregister_pm_notifier(sdio_ctx);
740 #endif
741
742     kfree(sdio_ctx);
743
744 } /* uf_sdio_remove */
745
746
747 /*
748  * ---------------------------------------------------------------------------
749  *  uf_glue_sdio_suspend
750  *
751  *      System suspend callback.
752  *
753  * Arguments:
754  *      fdev            SDIO device
755  *
756  * Returns:
757  *
758  * ---------------------------------------------------------------------------
759  */
760 static void
761 uf_glue_sdio_suspend(struct sdioemb_dev *fdev)
762 {
763     unifi_info(NULL, "Suspending...\n");
764
765 } /* uf_glue_sdio_suspend() */
766
767
768 /*
769  * ---------------------------------------------------------------------------
770  *  uf_glue_sdio_resume
771  *
772  *      System resume callback.
773  *
774  * Arguments:
775  *      fdev            SDIO device
776  *
777  * Returns:
778  *
779  * ---------------------------------------------------------------------------
780  */
781 static void
782 uf_glue_sdio_resume(struct sdioemb_dev *fdev)
783 {
784     unifi_info(NULL, "Resuming...\n");
785
786 #ifdef ANDROID_BUILD
787     unifi_trace(NULL, UDBG1, "emb resume: take wakelock\n");
788     wake_lock(&unifi_sdio_wake_lock);
789 #endif
790
791 } /* uf_glue_sdio_resume() */
792
793
794
795
796 static struct sdioemb_func_driver unifi_sdioemb = {
797     .name = "unifi",
798     .id_table = NULL,           /* Filled in when main driver registers */
799
800     .probe  = uf_glue_sdio_probe,
801     .remove = uf_sdio_remove,
802     .card_int_handler = uf_glue_sdio_int_handler,
803     .suspend  = uf_glue_sdio_suspend,
804     .resume = uf_glue_sdio_resume,
805 };
806
807
808 /*
809  * ---------------------------------------------------------------------------
810  *  CsrSdioFunctionDriverRegister
811  *  CsrSdioFunctionDriverUnregister
812  *
813  *      These functions are called from the main module load and unload
814  *      functions. They perform the appropriate operations for the
815  *      SDIOemb driver.
816  *
817  *  Arguments:
818  *      None.
819  *
820  *  Returns:
821  *      None.
822  * ---------------------------------------------------------------------------
823  */
824 CsrResult
825 CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
826 {
827     int r;
828     int i;
829
830     printk("Unifi: Using CSR embedded SDIO driver\n");
831
832     if (sdio_func_drv) {
833         unifi_error(NULL, "sdio_emb: UniFi driver already registered\n");
834         return CSR_SDIO_RESULT_INVALID_VALUE;
835     }
836
837     /* Build ID table to pass to sdioemb */
838     unifi_sdioemb.id_table = CsrPmemAlloc(sizeof(struct sdioemb_id_table) * (sdio_drv->idsCount + 1));
839     if (unifi_sdioemb.id_table == NULL) {
840         unifi_error(NULL, "sdio_emb: Failed to allocate memory for ID table (%d IDs)\n", sdio_drv->idsCount);
841         return CSR_RESULT_FAILURE;
842     }
843     for (i = 0; i < sdio_drv->idsCount; i++) {
844         unifi_sdioemb.id_table[i].vendor_id = sdio_drv->ids[i].manfId;
845         unifi_sdioemb.id_table[i].device_id = sdio_drv->ids[i].cardId;
846         unifi_sdioemb.id_table[i].function  = sdio_drv->ids[i].sdioFunction;
847         unifi_sdioemb.id_table[i].interface = sdio_drv->ids[i].sdioInterface;
848     }
849     unifi_sdioemb.id_table[i].vendor_id = 0;
850     unifi_sdioemb.id_table[i].device_id = 0;
851     unifi_sdioemb.id_table[i].function  = 0;
852     unifi_sdioemb.id_table[i].interface = 0;
853
854     /* Save the registered driver description */
855     sdio_func_drv = sdio_drv;
856
857 #ifdef CONFIG_PM
858     /* Initialise PM notifier list */
859     INIT_LIST_HEAD(&uf_sdio_emb_pm_notifiers.list);
860 #endif
861
862 #ifdef ANDROID_BUILD
863     wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
864 #endif
865
866     /* Register ourself with sdioemb */
867     r = sdioemb_driver_register(&unifi_sdioemb);
868     if (r) {
869         unifi_error(NULL, "Failed to register UniFi SDIO driver: %d\n", r);
870         return ConvertSdioToCsrSdioResult(r);
871     }
872
873     return CSR_RESULT_SUCCESS;
874 } /* CsrSdioFunctionDriverRegister() */
875
876
877 void
878 CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
879 {
880     sdioemb_driver_unregister(&unifi_sdioemb);
881
882 #ifdef ANDROID_BUILD
883     wake_lock_destroy(&unifi_sdio_wake_lock);
884 #endif
885
886     sdio_func_drv = NULL;
887
888     CsrPmemFree(unifi_sdioemb.id_table);
889     unifi_sdioemb.id_table = NULL;
890 } /* CsrSdioFunctionDriverUnregister() */
891