staging: brcm80211: replace MFREE with kfree
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / brcm80211 / brcmfmac / bcmsdh_linux.c
CommitLineData
cf2b4488
HP
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/**
18 * @file bcmsdh_linux.c
19 */
20
21#define __UNDEF_NO_VERSION__
22
23#include <typedefs.h>
24#include <linuxver.h>
25
26#include <linux/pci.h>
27#include <linux/completion.h>
28
29#include <osl.h>
30#include <pcicfg.h>
31#include <bcmdefs.h>
32#include <bcmdevs.h>
33
34#if defined(OOB_INTR_ONLY)
35#include <linux/irq.h>
36extern void dhdsdio_isr(void *args);
37#include <bcmutils.h>
38#include <dngl_stats.h>
39#include <dhd.h>
40#endif /* defined(OOB_INTR_ONLY) */
41#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270)
42#if !defined(BCMPLATFORM_BUS)
43#define BCMPLATFORM_BUS
44#endif /* !defined(BCMPLATFORM_BUS) */
45
46#include <linux/platform_device.h>
47#endif /* CONFIG_MACH_SANDGATE2G */
48
49/**
50 * SDIO Host Controller info
51 */
52typedef struct bcmsdh_hc bcmsdh_hc_t;
53
54struct bcmsdh_hc {
55 bcmsdh_hc_t *next;
56#ifdef BCMPLATFORM_BUS
57 struct device *dev; /* platform device handle */
58#else
59 struct pci_dev *dev; /* pci device handle */
60#endif /* BCMPLATFORM_BUS */
61 osl_t *osh;
62 void *regs; /* SDIO Host Controller address */
63 bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
64 void *ch;
65 unsigned int oob_irq;
66 unsigned long oob_flags; /* OOB Host specifiction
67 as edge and etc */
68 bool oob_irq_registered;
69#if defined(OOB_INTR_ONLY)
70 spinlock_t irq_lock;
71#endif
72};
5f782dee 73static bcmsdh_hc_t *sdhcinfo;
cf2b4488
HP
74
75/* driver info, initialized when bcmsdh_register is called */
76static bcmsdh_driver_t drvinfo = { NULL, NULL };
77
78/* debugging macros */
79#define SDLX_MSG(x)
80
81/**
82 * Checks to see if vendor and device IDs match a supported SDIO Host Controller.
83 */
7d4df48e 84bool bcmsdh_chipmatch(u16 vendor, u16 device)
cf2b4488
HP
85{
86 /* Add other vendors and devices as required */
87
88#ifdef BCMSDIOH_STD
89 /* Check for Arasan host controller */
90 if (vendor == VENDOR_SI_IMAGE)
0f0881b0 91 return true;
cf2b4488
HP
92
93 /* Check for BRCM 27XX Standard host controller */
94 if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM)
0f0881b0 95 return true;
cf2b4488
HP
96
97 /* Check for BRCM Standard host controller */
98 if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM)
0f0881b0 99 return true;
cf2b4488
HP
100
101 /* Check for TI PCIxx21 Standard host controller */
102 if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI)
0f0881b0 103 return true;
cf2b4488
HP
104
105 if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI)
0f0881b0 106 return true;
cf2b4488
HP
107
108 /* Ricoh R5C822 Standard SDIO Host */
109 if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH)
0f0881b0 110 return true;
cf2b4488
HP
111
112 /* JMicron Standard SDIO Host */
113 if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON)
0f0881b0 114 return true;
cf2b4488
HP
115#endif /* BCMSDIOH_STD */
116#ifdef BCMSDIOH_SPI
117 /* This is the PciSpiHost. */
118 if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) {
119 printf("Found PCI SPI Host Controller\n");
0f0881b0 120 return true;
cf2b4488
HP
121 }
122#endif /* BCMSDIOH_SPI */
123
0965ae88 124 return false;
cf2b4488
HP
125}
126
127#if defined(BCMPLATFORM_BUS)
128#if defined(BCMLXSDMMC)
129/* forward declarations */
130int bcmsdh_probe(struct device *dev);
131EXPORT_SYMBOL(bcmsdh_probe);
132
133int bcmsdh_remove(struct device *dev);
134EXPORT_SYMBOL(bcmsdh_remove);
135
136#else
137/* forward declarations */
138static int __devinit bcmsdh_probe(struct device *dev);
139static int __devexit bcmsdh_remove(struct device *dev);
140#endif /* BCMLXSDMMC */
141
142#ifndef BCMLXSDMMC
143static struct device_driver bcmsdh_driver = {
144 .name = "pxa2xx-mci",
145 .bus = &platform_bus_type,
146 .probe = bcmsdh_probe,
147 .remove = bcmsdh_remove,
148 .suspend = NULL,
149 .resume = NULL,
150};
151#endif /* BCMLXSDMMC */
152
153#ifndef BCMLXSDMMC
154static
155#endif /* BCMLXSDMMC */
156int bcmsdh_probe(struct device *dev)
157{
158 osl_t *osh = NULL;
159 bcmsdh_hc_t *sdhc = NULL;
3deea904 160 unsigned long regs = 0;
cf2b4488
HP
161 bcmsdh_info_t *sdh = NULL;
162#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
163 struct platform_device *pdev;
164 struct resource *r;
165#endif /* BCMLXSDMMC */
166 int irq = 0;
66cbd3ab 167 u32 vendevid;
cf2b4488
HP
168 unsigned long irq_flags = 0;
169
170#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
171 pdev = to_platform_device(dev);
172 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
173 irq = platform_get_irq(pdev, 0);
174 if (!r || irq == NO_IRQ)
175 return -ENXIO;
176#endif /* BCMLXSDMMC */
177
178#if defined(OOB_INTR_ONLY)
179#ifdef HW_OOB
180 irq_flags =
181 IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
182 IORESOURCE_IRQ_SHAREABLE;
183#else
184 irq_flags = IRQF_TRIGGER_FALLING;
185#endif /* HW_OOB */
186 irq = dhd_customer_oob_irq_map(&irq_flags);
187 if (irq < 0) {
188 SDLX_MSG(("%s: Host irq is not defined\n", __func__));
189 return 1;
190 }
191#endif /* defined(OOB_INTR_ONLY) */
192 /* allocate SDIO Host Controller state info */
0965ae88 193 osh = osl_attach(dev, PCI_BUS, false);
81e95f9d 194 if (!osh) {
cf2b4488
HP
195 SDLX_MSG(("%s: osl_attach failed\n", __func__));
196 goto err;
197 }
5fcc1fcb 198 sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC);
81e95f9d 199 if (!sdhc) {
97e17d0e 200 SDLX_MSG(("%s: out of memory\n", __func__));
cf2b4488
HP
201 goto err;
202 }
cf2b4488
HP
203 sdhc->osh = osh;
204
205 sdhc->dev = (void *)dev;
206
207#ifdef BCMLXSDMMC
81e95f9d
JC
208 sdh = bcmsdh_attach(osh, (void *)0, (void **)&regs, irq);
209 if (!sdh) {
cf2b4488
HP
210 SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
211 goto err;
212 }
213#else
81e95f9d
JC
214 sdh = bcmsdh_attach(osh, (void *)r->start, (void **)&regs, irq);
215 if (!sdh) {
cf2b4488
HP
216 SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
217 goto err;
218 }
219#endif /* BCMLXSDMMC */
220 sdhc->sdh = sdh;
221 sdhc->oob_irq = irq;
222 sdhc->oob_flags = irq_flags;
0965ae88 223 sdhc->oob_irq_registered = false; /* to make sure.. */
cf2b4488
HP
224#if defined(OOB_INTR_ONLY)
225 spin_lock_init(&sdhc->irq_lock);
226#endif
227
228 /* chain SDIO Host Controller info together */
229 sdhc->next = sdhcinfo;
230 sdhcinfo = sdhc;
231 /* Read the vendor/device ID from the CIS */
232 vendevid = bcmsdh_query_device(sdh);
233
234 /* try to attach to the target device */
81e95f9d
JC
235 sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
236 0, 0, 0, 0, (void *)regs, NULL, sdh);
237 if (!sdhc->ch) {
cf2b4488
HP
238 SDLX_MSG(("%s: device attach failed\n", __func__));
239 goto err;
240 }
241
242 return 0;
243
244 /* error handling */
245err:
246 if (sdhc) {
247 if (sdhc->sdh)
248 bcmsdh_detach(sdhc->osh, sdhc->sdh);
182acb3c 249 kfree(sdhc);
cf2b4488
HP
250 }
251 if (osh)
252 osl_detach(osh);
253 return -ENODEV;
254}
255
256#ifndef BCMLXSDMMC
257static
258#endif /* BCMLXSDMMC */
259int bcmsdh_remove(struct device *dev)
260{
261 bcmsdh_hc_t *sdhc, *prev;
262 osl_t *osh;
263
264 sdhc = sdhcinfo;
265 drvinfo.detach(sdhc->ch);
266 bcmsdh_detach(sdhc->osh, sdhc->sdh);
267 /* find the SDIO Host Controller state for this pdev
268 and take it out from the list */
269 for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
270 if (sdhc->dev == (void *)dev) {
271 if (prev)
272 prev->next = sdhc->next;
273 else
274 sdhcinfo = NULL;
275 break;
276 }
277 prev = sdhc;
278 }
279 if (!sdhc) {
280 SDLX_MSG(("%s: failed\n", __func__));
281 return 0;
282 }
283
284 /* release SDIO Host Controller info */
285 osh = sdhc->osh;
182acb3c 286 kfree(sdhc);
cf2b4488
HP
287 osl_detach(osh);
288
289#if !defined(BCMLXSDMMC)
290 dev_set_drvdata(dev, NULL);
291#endif /* !defined(BCMLXSDMMC) */
292
293 return 0;
294}
295
296#else /* BCMPLATFORM_BUS */
297
298#if !defined(BCMLXSDMMC)
299/* forward declarations for PCI probe and remove functions. */
300static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev,
301 const struct pci_device_id *ent);
302static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev);
303
304/**
305 * pci id table
306 */
307static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = {
308{
309 .vendor = PCI_ANY_ID,
310 .device = PCI_ANY_ID,
311 .subvendor = PCI_ANY_ID,
312 .subdevice = PCI_ANY_ID,
313 .class = 0,
314 .class_mask = 0,
315 .driver_data = 0,
316},
317{0,}
318};
319
320MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid);
321
322/**
323 * SDIO Host Controller pci driver info
324 */
325static struct pci_driver bcmsdh_pci_driver = {
326 .node = {},
327 .name = "bcmsdh",
328 .id_table = bcmsdh_pci_devid,
329 .probe = bcmsdh_pci_probe,
330 .remove = bcmsdh_pci_remove,
331 .suspend = NULL,
332 .resume = NULL,
333};
334
335extern uint sd_pci_slot; /* Force detection to a particular PCI */
336 /* slot only . Allows for having multiple */
337 /* WL devices at once in a PC */
338 /* Only one instance of dhd will be */
339 /* usable at a time */
340 /* Upper word is bus number, */
341 /* lower word is slot number */
342 /* Default value of 0xFFFFffff turns this */
343 /* off */
344module_param(sd_pci_slot, uint, 0);
345
346/**
347 * Detect supported SDIO Host Controller and attach if found.
348 *
349 * Determine if the device described by pdev is a supported SDIO Host
350 * Controller. If so, attach to it and attach to the target device.
351 */
352static int __devinit
353bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
354{
355 osl_t *osh = NULL;
356 bcmsdh_hc_t *sdhc = NULL;
3deea904 357 unsigned long regs;
cf2b4488
HP
358 bcmsdh_info_t *sdh = NULL;
359 int rc;
360
361 if (sd_pci_slot != 0xFFFFffff) {
362 if (pdev->bus->number != (sd_pci_slot >> 16) ||
363 PCI_SLOT(pdev->devfn) != (sd_pci_slot & 0xffff)) {
364 SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n",
365 __func__,
366 bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
367 "Found compatible SDIOHC" :
368 "Probing unknown device",
369 pdev->bus->number, PCI_SLOT(pdev->devfn),
370 pdev->vendor, pdev->device));
371 return -ENODEV;
372 }
373 SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X "
374 "(good PCI location)\n", __func__,
375 bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
376 "Using compatible SDIOHC" : "WARNING, forced use "
377 "of unkown device",
378 pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor,
379 pdev->device));
380 }
381
382 if ((pdev->vendor == VENDOR_TI)
383 && ((pdev->device == PCIXX21_FLASHMEDIA_ID)
384 || (pdev->device == PCIXX21_FLASHMEDIA0_ID))) {
66cbd3ab 385 u32 config_reg;
cf2b4488
HP
386
387 SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n",
388 __func__));
0965ae88 389 osh = osl_attach(pdev, PCI_BUS, false);
81e95f9d 390 if (!osh) {
cf2b4488
HP
391 SDLX_MSG(("%s: osl_attach failed\n", __func__));
392 goto err;
393 }
394
395 config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4);
396
397 /*
398 * Set MMC_SD_DIS bit in FlashMedia Controller.
399 * Disbling the SD/MMC Controller in the FlashMedia Controller
400 * allows the Standard SD Host Controller to take over control
401 * of the SD Slot.
402 */
403 config_reg |= 0x02;
404 OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg);
405 osl_detach(osh);
406 }
407 /* match this pci device with what we support */
408 /* we can't solely rely on this to believe it is
409 our SDIO Host Controller! */
410 if (!bcmsdh_chipmatch(pdev->vendor, pdev->device))
411 return -ENODEV;
412
413 /* this is a pci device we might support */
414 SDLX_MSG(("%s: Found possible SDIO Host Controller: "
415 "bus %d slot %d func %d irq %d\n", __func__,
416 pdev->bus->number, PCI_SLOT(pdev->devfn),
417 PCI_FUNC(pdev->devfn), pdev->irq));
418
419 /* use bcmsdh_query_device() to get the vendor ID of the target device
420 * so it will eventually appear in the Broadcom string on the console
421 */
422
423 /* allocate SDIO Host Controller state info */
0965ae88 424 osh = osl_attach(pdev, PCI_BUS, false);
81e95f9d 425 if (!osh) {
cf2b4488
HP
426 SDLX_MSG(("%s: osl_attach failed\n", __func__));
427 goto err;
428 }
5fcc1fcb 429 sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC);
81e95f9d 430 if (!sdhc) {
97e17d0e 431 SDLX_MSG(("%s: out of memory\n", __func__));
cf2b4488
HP
432 goto err;
433 }
cf2b4488
HP
434 sdhc->osh = osh;
435
436 sdhc->dev = pdev;
437
438 /* map to address where host can access */
439 pci_set_master(pdev);
440 rc = pci_enable_device(pdev);
441 if (rc) {
442 SDLX_MSG(("%s: Cannot enable PCI device\n", __func__));
443 goto err;
444 }
81e95f9d
JC
445 sdh = bcmsdh_attach(osh, (void *)(uintptr) pci_resource_start(pdev, 0),
446 (void **)&regs, pdev->irq);
447 if (!sdh) {
cf2b4488
HP
448 SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
449 goto err;
450 }
451
452 sdhc->sdh = sdh;
453
454 /* try to attach to the target device */
81e95f9d
JC
455 sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */
456 bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0,
457 (void *)regs, NULL, sdh);
458 if (!sdhc->ch) {
cf2b4488
HP
459 SDLX_MSG(("%s: device attach failed\n", __func__));
460 goto err;
461 }
462
463 /* chain SDIO Host Controller info together */
464 sdhc->next = sdhcinfo;
465 sdhcinfo = sdhc;
466
467 return 0;
468
469 /* error handling */
470err:
471 if (sdhc->sdh)
472 bcmsdh_detach(sdhc->osh, sdhc->sdh);
473 if (sdhc)
182acb3c 474 kfree(sdhc);
cf2b4488
HP
475 if (osh)
476 osl_detach(osh);
477 return -ENODEV;
478}
479
480/**
481 * Detach from target devices and SDIO Host Controller
482 */
483static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev)
484{
485 bcmsdh_hc_t *sdhc, *prev;
486 osl_t *osh;
487
488 /* find the SDIO Host Controller state for this
489 pdev and take it out from the list */
490 for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
491 if (sdhc->dev == pdev) {
492 if (prev)
493 prev->next = sdhc->next;
494 else
495 sdhcinfo = NULL;
496 break;
497 }
498 prev = sdhc;
499 }
500 if (!sdhc)
501 return;
502
503 drvinfo.detach(sdhc->ch);
504
505 bcmsdh_detach(sdhc->osh, sdhc->sdh);
506
507 /* release SDIO Host Controller info */
508 osh = sdhc->osh;
182acb3c 509 kfree(sdhc);
cf2b4488
HP
510 osl_detach(osh);
511}
512#endif /* BCMLXSDMMC */
513#endif /* BCMPLATFORM_BUS */
514
515extern int sdio_function_init(void);
516
517int bcmsdh_register(bcmsdh_driver_t *driver)
518{
519 int error = 0;
520
521 drvinfo = *driver;
522
523#if defined(BCMPLATFORM_BUS)
524#if defined(BCMLXSDMMC)
525 SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
526 error = sdio_function_init();
527#else
528 SDLX_MSG(("Intel PXA270 SDIO Driver\n"));
529 error = driver_register(&bcmsdh_driver);
530#endif /* defined(BCMLXSDMMC) */
531 return error;
532#endif /* defined(BCMPLATFORM_BUS) */
533
534#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
81e95f9d
JC
535 error = pci_register_driver(&bcmsdh_pci_driver);
536 if (!error)
cf2b4488
HP
537 return 0;
538
8ba9cfdb 539 SDLX_MSG(("%s: pci_register_driver failed 0x%x\n", __func__, error));
cf2b4488
HP
540#endif /* BCMPLATFORM_BUS */
541
542 return error;
543}
544
545extern void sdio_function_cleanup(void);
546
547void bcmsdh_unregister(void)
548{
549#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
550 driver_unregister(&bcmsdh_driver);
551#endif
552#if defined(BCMLXSDMMC)
553 sdio_function_cleanup();
554#endif /* BCMLXSDMMC */
555#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
556 pci_unregister_driver(&bcmsdh_pci_driver);
557#endif /* BCMPLATFORM_BUS */
558}
559
560#if defined(OOB_INTR_ONLY)
561void bcmsdh_oob_intr_set(bool enable)
562{
563 static bool curstate = 1;
564 unsigned long flags;
565
566 spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
567 if (curstate != enable) {
568 if (enable)
569 enable_irq(sdhcinfo->oob_irq);
570 else
571 disable_irq_nosync(sdhcinfo->oob_irq);
572 curstate = enable;
573 }
574 spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
575}
576
577static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
578{
579 dhd_pub_t *dhdp;
580
581 dhdp = (dhd_pub_t *) dev_get_drvdata(sdhcinfo->dev);
582
583 bcmsdh_oob_intr_set(0);
584
585 if (dhdp == NULL) {
586 SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
587 return IRQ_HANDLED;
588 }
589
590 WAKE_LOCK_TIMEOUT(dhdp, WAKE_LOCK_TMOUT, 25);
591
592 dhdsdio_isr((void *)dhdp->bus);
593
594 return IRQ_HANDLED;
595}
596
597int bcmsdh_register_oob_intr(void *dhdp)
598{
599 int error = 0;
600
601 SDLX_MSG(("%s Enter\n", __func__));
602
603 sdhcinfo->oob_flags =
604 IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
605 IORESOURCE_IRQ_SHAREABLE;
606 dev_set_drvdata(sdhcinfo->dev, dhdp);
607
608 if (!sdhcinfo->oob_irq_registered) {
609 SDLX_MSG(("%s IRQ=%d Type=%X\n", __func__,
610 (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags));
611 /* Refer to customer Host IRQ docs about
612 proper irqflags definition */
613 error =
614 request_irq(sdhcinfo->oob_irq, wlan_oob_irq,
615 sdhcinfo->oob_flags, "bcmsdh_sdmmc", NULL);
616 if (error)
617 return -ENODEV;
618
619 set_irq_wake(sdhcinfo->oob_irq, 1);
0f0881b0 620 sdhcinfo->oob_irq_registered = true;
cf2b4488
HP
621 }
622
623 return 0;
624}
625
626void bcmsdh_unregister_oob_intr(void)
627{
628 SDLX_MSG(("%s: Enter\n", __func__));
629
630 set_irq_wake(sdhcinfo->oob_irq, 0);
631 disable_irq(sdhcinfo->oob_irq); /* just in case.. */
632 free_irq(sdhcinfo->oob_irq, NULL);
0965ae88 633 sdhcinfo->oob_irq_registered = false;
cf2b4488
HP
634}
635#endif /* defined(OOB_INTR_ONLY) */
636/* Module parameters specific to each host-controller driver */
637
638extern uint sd_msglevel; /* Debug message level */
639module_param(sd_msglevel, uint, 0);
640
641extern uint sd_power; /* 0 = SD Power OFF,
642 1 = SD Power ON. */
643module_param(sd_power, uint, 0);
644
645extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF,
646 1 = SD Clock ON */
647module_param(sd_clock, uint, 0);
648
649extern uint sd_divisor; /* Divisor (-1 means external clock) */
650module_param(sd_divisor, uint, 0);
651
652extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */
653module_param(sd_sdmode, uint, 0);
654
655extern uint sd_hiok; /* Ok to use hi-speed mode */
656module_param(sd_hiok, uint, 0);
657
658extern uint sd_f2_blocksize;
659module_param(sd_f2_blocksize, int, 0);