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