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.12 2010/03/10 03:09:48 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; 79 }; 80 static bcmsdh_hc_t *sdhcinfo = NULL; 81 82 /* driver info, initialized when bcmsdh_register is called */ 83 static bcmsdh_driver_t drvinfo = {NULL, NULL}; 84 85 /* debugging macros */ 86 #define SDLX_MSG(x) 87 88 /** 89 * Checks to see if vendor and device IDs match a supported SDIO Host Controller. 90 */ 91 bool 92 bcmsdh_chipmatch(uint16 vendor, uint16 device) 93 { 94 /* Add other vendors and devices as required */ 95 96 #ifdef BCMSDIOH_STD 97 /* Check for Arasan host controller */ 98 if (vendor == VENDOR_SI_IMAGE) { 99 return (TRUE); 100 } 101 /* Check for BRCM 27XX Standard host controller */ 102 if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) { 103 return (TRUE); 104 } 105 /* Check for BRCM Standard host controller */ 106 if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) { 107 return (TRUE); 108 } 109 /* Check for TI PCIxx21 Standard host controller */ 110 if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) { 111 return (TRUE); 112 } 113 if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) { 114 return (TRUE); 115 } 116 /* Ricoh R5C822 Standard SDIO Host */ 117 if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) { 118 return (TRUE); 119 } 120 /* JMicron Standard SDIO Host */ 121 if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) { 122 return (TRUE); 123 } 124 125 #endif /* BCMSDIOH_STD */ 126 #ifdef BCMSDIOH_SPI 127 /* This is the PciSpiHost. */ 128 if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { 129 printf("Found PCI SPI Host Controller\n"); 130 return (TRUE); 131 } 132 133 #endif /* BCMSDIOH_SPI */ 134 135 return (FALSE); 136 } 137 138 #if defined(BCMPLATFORM_BUS) 139 #if defined(BCMLXSDMMC) 140 /* forward declarations */ 141 int bcmsdh_probe(struct device *dev); 142 int bcmsdh_remove(struct device *dev); 143 144 EXPORT_SYMBOL(bcmsdh_probe); 145 EXPORT_SYMBOL(bcmsdh_remove); 146 147 #else 148 /* forward declarations */ 149 static int __devinit bcmsdh_probe(struct device *dev); 150 static int __devexit bcmsdh_remove(struct device *dev); 151 #endif /* BCMLXSDMMC */ 152 153 #ifndef BCMLXSDMMC 154 static struct device_driver bcmsdh_driver = { 155 .name = "pxa2xx-mci", 156 .bus = &platform_bus_type, 157 .probe = bcmsdh_probe, 158 .remove = bcmsdh_remove, 159 .suspend = NULL, 160 .resume = NULL, 161 }; 162 #endif /* BCMLXSDMMC */ 163 164 #ifndef BCMLXSDMMC 165 static 166 #endif /* BCMLXSDMMC */ 167 int bcmsdh_probe(struct device *dev) 168 { 169 osl_t *osh = NULL; 170 bcmsdh_hc_t *sdhc = NULL; 171 ulong regs = 0; 172 bcmsdh_info_t *sdh = NULL; 173 #if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) 174 struct platform_device *pdev; 175 struct resource *r; 176 #endif /* BCMLXSDMMC */ 177 int irq = 0; 178 uint32 vendevid; 179 unsigned long irq_flags = IRQF_TRIGGER_FALLING; 180 181 #if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) 182 pdev = to_platform_device(dev); 183 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 184 irq = platform_get_irq(pdev, 0); 185 if (!r || irq == NO_IRQ) 186 return -ENXIO; 187 #endif /* BCMLXSDMMC */ 188 189 #if defined(OOB_INTR_ONLY) 190 irq = dhd_customer_oob_irq_map(&irq_flags); 191 if (irq < 0) { 192 SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__)); 193 return 1; 194 } 195 #endif /* defined(OOB_INTR_ONLY) */ 196 /* allocate SDIO Host Controller state info */ 197 if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) { 198 SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 199 goto err; 200 } 201 if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { 202 SDLX_MSG(("%s: out of memory, allocated %d bytes\n", 203 __FUNCTION__, 204 MALLOCED(osh))); 205 goto err; 206 } 207 bzero(sdhc, sizeof(bcmsdh_hc_t)); 208 sdhc->osh = osh; 209 210 sdhc->dev = (void *)dev; 211 212 #ifdef BCMLXSDMMC 213 if (!(sdh = bcmsdh_attach(osh, (void *)0, 214 (void **)®s, irq))) { 215 SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 216 goto err; 217 } 218 #else 219 if (!(sdh = bcmsdh_attach(osh, (void *)r->start, 220 (void **)®s, irq))) { 221 SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 222 goto err; 223 } 224 #endif /* BCMLXSDMMC */ 225 sdhc->sdh = sdh; 226 sdhc->oob_irq = irq; 227 sdhc->oob_flags = irq_flags; 228 229 /* chain SDIO Host Controller info together */ 230 sdhc->next = sdhcinfo; 231 sdhcinfo = sdhc; 232 /* Read the vendor/device ID from the CIS */ 233 vendevid = bcmsdh_query_device(sdh); 234 235 /* try to attach to the target device */ 236 if (!(sdhc->ch = drvinfo.attach((vendevid >> 16), 237 (vendevid & 0xFFFF), 0, 0, 0, 0, 238 (void *)regs, NULL, sdh))) { 239 SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); 240 goto err; 241 } 242 243 return 0; 244 245 /* error handling */ 246 err: 247 if (sdhc) { 248 if (sdhc->sdh) 249 bcmsdh_detach(sdhc->osh, sdhc->sdh); 250 MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 251 } 252 if (osh) 253 osl_detach(osh); 254 return -ENODEV; 255 } 256 257 #ifndef BCMLXSDMMC 258 static 259 #endif /* BCMLXSDMMC */ 260 int bcmsdh_remove(struct device *dev) 261 { 262 bcmsdh_hc_t *sdhc, *prev; 263 osl_t *osh; 264 265 sdhc = sdhcinfo; 266 drvinfo.detach(sdhc->ch); 267 bcmsdh_detach(sdhc->osh, sdhc->sdh); 268 /* find the SDIO Host Controller state for this pdev 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", __FUNCTION__)); 281 return 0; 282 } 283 284 285 /* release SDIO Host Controller info */ 286 osh = sdhc->osh; 287 MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 288 osl_detach(osh); 289 290 #if !defined(BCMLXSDMMC) 291 dev_set_drvdata(dev, NULL); 292 #endif /* !defined(BCMLXSDMMC) */ 293 294 return 0; 295 } 296 297 #else /* BCMPLATFORM_BUS */ 298 299 #if !defined(BCMLXSDMMC) 300 /* forward declarations for PCI probe and remove functions. */ 301 static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 302 static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); 303 304 /** 305 * pci id table 306 */ 307 static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { 308 { vendor: PCI_ANY_ID, 309 device: PCI_ANY_ID, 310 subvendor: PCI_ANY_ID, 311 subdevice: PCI_ANY_ID, 312 class: 0, 313 class_mask: 0, 314 driver_data: 0, 315 }, 316 { 0, } 317 }; 318 MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); 319 320 /** 321 * SDIO Host Controller pci driver info 322 */ 323 static struct pci_driver bcmsdh_pci_driver = { 324 node: {}, 325 name: "bcmsdh", 326 id_table: bcmsdh_pci_devid, 327 probe: bcmsdh_pci_probe, 328 remove: bcmsdh_pci_remove, 329 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 330 save_state: NULL, 331 #endif 332 suspend: NULL, 333 resume: NULL, 334 }; 335 336 337 extern uint sd_pci_slot; /* Force detection to a particular PCI */ 338 /* slot only . Allows for having multiple */ 339 /* WL devices at once in a PC */ 340 /* Only one instance of dhd will be */ 341 /* useable at a time */ 342 /* Upper word is bus number, */ 343 /* lower word is slot number */ 344 /* Default value of 0xFFFFffff turns this */ 345 /* off */ 346 module_param(sd_pci_slot, uint, 0); 347 348 349 /** 350 * Detect supported SDIO Host Controller and attach if found. 351 * 352 * Determine if the device described by pdev is a supported SDIO Host 353 * Controller. If so, attach to it and attach to the target device. 354 */ 355 static int __devinit 356 bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 357 { 358 osl_t *osh = NULL; 359 bcmsdh_hc_t *sdhc = NULL; 360 ulong regs; 361 bcmsdh_info_t *sdh = NULL; 362 int rc; 363 364 if (sd_pci_slot != 0xFFFFffff) { 365 if (pdev->bus->number != (sd_pci_slot>>16) || 366 PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) { 367 SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n", 368 __FUNCTION__, 369 bcmsdh_chipmatch(pdev->vendor, pdev->device) 370 ? "Found compatible SDIOHC" 371 : "Probing unknown device", 372 pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, 373 pdev->device)); 374 return -ENODEV; 375 } 376 SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n", 377 __FUNCTION__, 378 bcmsdh_chipmatch(pdev->vendor, pdev->device) 379 ? "Using compatible SDIOHC" 380 : "WARNING, forced use of unkown device", 381 pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device)); 382 } 383 384 if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) || 385 (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { 386 uint32 config_reg; 387 388 SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__)); 389 if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { 390 SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 391 goto err; 392 } 393 394 config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); 395 396 /* 397 * Set MMC_SD_DIS bit in FlashMedia Controller. 398 * Disbling the SD/MMC Controller in the FlashMedia Controller 399 * allows the Standard SD Host Controller to take over control 400 * of the SD Slot. 401 */ 402 config_reg |= 0x02; 403 OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); 404 osl_detach(osh); 405 } 406 /* match this pci device with what we support */ 407 /* we can't solely rely on this to believe it is our SDIO Host Controller! */ 408 if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { 409 return -ENODEV; 410 } 411 412 /* this is a pci device we might support */ 413 SDLX_MSG(("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n", 414 __FUNCTION__, 415 pdev->bus->number, PCI_SLOT(pdev->devfn), 416 PCI_FUNC(pdev->devfn), pdev->irq)); 417 418 /* use bcmsdh_query_device() to get the vendor ID of the target device so 419 * it will eventually appear in the Broadcom string on the console 420 */ 421 422 /* allocate SDIO Host Controller state info */ 423 if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { 424 SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 425 goto err; 426 } 427 if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { 428 SDLX_MSG(("%s: out of memory, allocated %d bytes\n", 429 __FUNCTION__, 430 MALLOCED(osh))); 431 goto err; 432 } 433 bzero(sdhc, sizeof(bcmsdh_hc_t)); 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 enble PCI device\n", __FUNCTION__)); 443 goto err; 444 } 445 if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0), 446 (void **)®s, pdev->irq))) { 447 SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 448 goto err; 449 } 450 451 sdhc->sdh = sdh; 452 453 /* try to attach to the target device */ 454 if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ 455 bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, 456 (void *)regs, NULL, sdh))) { 457 SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); 458 goto err; 459 } 460 461 /* chain SDIO Host Controller info together */ 462 sdhc->next = sdhcinfo; 463 sdhcinfo = sdhc; 464 465 return 0; 466 467 /* error handling */ 468 err: 469 if (sdhc->sdh) 470 bcmsdh_detach(sdhc->osh, sdhc->sdh); 471 if (sdhc) 472 MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 473 if (osh) 474 osl_detach(osh); 475 return -ENODEV; 476 } 477 478 479 /** 480 * Detach from target devices and SDIO Host Controller 481 */ 482 static void __devexit 483 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 pdev and take it out from the list */ 489 for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { 490 if (sdhc->dev == pdev) { 491 if (prev) 492 prev->next = sdhc->next; 493 else 494 sdhcinfo = NULL; 495 break; 496 } 497 prev = sdhc; 498 } 499 if (!sdhc) 500 return; 501 502 drvinfo.detach(sdhc->ch); 503 504 bcmsdh_detach(sdhc->osh, sdhc->sdh); 505 506 /* release SDIO Host Controller info */ 507 osh = sdhc->osh; 508 MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 509 osl_detach(osh); 510 } 511 #endif /* BCMLXSDMMC */ 512 #endif /* BCMPLATFORM_BUS */ 513 514 extern int sdio_function_init(void); 515 516 int 517 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) 535 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 536 if (!(error = pci_module_init(&bcmsdh_pci_driver))) 537 return 0; 538 #else 539 if (!(error = pci_register_driver(&bcmsdh_pci_driver))) 540 return 0; 541 #endif 542 543 SDLX_MSG(("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error)); 544 #endif /* BCMPLATFORM_BUS */ 545 546 return error; 547 } 548 549 extern void sdio_function_cleanup(void); 550 551 void 552 bcmsdh_unregister(void) 553 { 554 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 555 if (bcmsdh_pci_driver.node.next) 556 #endif 557 558 #if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) 559 driver_unregister(&bcmsdh_driver); 560 #endif 561 #if defined(BCMLXSDMMC) 562 sdio_function_cleanup(); 563 #endif /* BCMLXSDMMC */ 564 #if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) 565 pci_unregister_driver(&bcmsdh_pci_driver); 566 #endif /* BCMPLATFORM_BUS */ 567 } 568 569 #if defined(OOB_INTR_ONLY) 570 static irqreturn_t wlan_oob_irq(int irq, void *dev_id) 571 { 572 dhd_pub_t *dhdp; 573 574 dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev); 575 576 if (dhdp == NULL) { 577 disable_irq(sdhcinfo->oob_irq); 578 SDLX_MSG(("Out of band GPIO interrupt fired way too early\n")); 579 return IRQ_HANDLED; 580 } 581 582 dhdsdio_isr((void *)dhdp->bus); 583 584 return IRQ_HANDLED; 585 } 586 587 int bcmsdh_register_oob_intr(void * dhdp) 588 { 589 int error = 0; 590 591 SDLX_MSG(("%s Enter\n", __FUNCTION__)); 592 593 dev_set_drvdata(sdhcinfo->dev, dhdp); 594 595 /* Refer to customer Host IRQ docs about proper irqflags definition */ 596 error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags, 597 "bcmsdh_sdmmc", NULL); 598 599 if (error) 600 return -ENODEV; 601 602 set_irq_wake(sdhcinfo->oob_irq, 1); 603 604 return 0; 605 } 606 607 void bcmsdh_unregister_oob_intr(void) 608 { 609 SDLX_MSG(("%s: Enter\n", __FUNCTION__)); 610 611 set_irq_wake(sdhcinfo->oob_irq, 0); 612 disable_irq(sdhcinfo->oob_irq); /* just in case.. */ 613 free_irq(sdhcinfo->oob_irq, NULL); 614 } 615 616 void bcmsdh_oob_intr_set(bool enable) 617 { 618 if (enable) 619 enable_irq(sdhcinfo->oob_irq); 620 else 621 disable_irq(sdhcinfo->oob_irq); 622 } 623 #endif /* defined(OOB_INTR_ONLY) */ 624 /* Module parameters specific to each host-controller driver */ 625 626 extern uint sd_msglevel; /* Debug message level */ 627 module_param(sd_msglevel, uint, 0); 628 629 extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ 630 module_param(sd_power, uint, 0); 631 632 extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */ 633 module_param(sd_clock, uint, 0); 634 635 extern uint sd_divisor; /* Divisor (-1 means external clock) */ 636 module_param(sd_divisor, uint, 0); 637 638 extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ 639 module_param(sd_sdmode, uint, 0); 640 641 extern uint sd_hiok; /* Ok to use hi-speed mode */ 642 module_param(sd_hiok, uint, 0); 643 644 extern uint sd_f2_blocksize; 645 module_param(sd_f2_blocksize, int, 0); 646 647 648 #ifdef BCMSDH_MODULE 649 EXPORT_SYMBOL(bcmsdh_attach); 650 EXPORT_SYMBOL(bcmsdh_detach); 651 EXPORT_SYMBOL(bcmsdh_intr_query); 652 EXPORT_SYMBOL(bcmsdh_intr_enable); 653 EXPORT_SYMBOL(bcmsdh_intr_disable); 654 EXPORT_SYMBOL(bcmsdh_intr_reg); 655 EXPORT_SYMBOL(bcmsdh_intr_dereg); 656 657 #if defined(DHD_DEBUG) 658 EXPORT_SYMBOL(bcmsdh_intr_pending); 659 #endif 660 661 EXPORT_SYMBOL(bcmsdh_devremove_reg); 662 EXPORT_SYMBOL(bcmsdh_cfg_read); 663 EXPORT_SYMBOL(bcmsdh_cfg_write); 664 EXPORT_SYMBOL(bcmsdh_cis_read); 665 EXPORT_SYMBOL(bcmsdh_reg_read); 666 EXPORT_SYMBOL(bcmsdh_reg_write); 667 EXPORT_SYMBOL(bcmsdh_regfail); 668 EXPORT_SYMBOL(bcmsdh_send_buf); 669 EXPORT_SYMBOL(bcmsdh_recv_buf); 670 671 EXPORT_SYMBOL(bcmsdh_rwdata); 672 EXPORT_SYMBOL(bcmsdh_abort); 673 EXPORT_SYMBOL(bcmsdh_query_device); 674 EXPORT_SYMBOL(bcmsdh_query_iofnum); 675 EXPORT_SYMBOL(bcmsdh_iovar_op); 676 EXPORT_SYMBOL(bcmsdh_register); 677 EXPORT_SYMBOL(bcmsdh_unregister); 678 EXPORT_SYMBOL(bcmsdh_chipmatch); 679 EXPORT_SYMBOL(bcmsdh_reset); 680 681 EXPORT_SYMBOL(bcmsdh_get_dstatus); 682 EXPORT_SYMBOL(bcmsdh_cfg_read_word); 683 EXPORT_SYMBOL(bcmsdh_cfg_write_word); 684 EXPORT_SYMBOL(bcmsdh_cur_sbwad); 685 EXPORT_SYMBOL(bcmsdh_chipinfo); 686 687 #endif /* BCMSDH_MODULE */ 688