18ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* 28ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * SDIO access interface for drivers - linux specific (pci only) 38ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 4832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt * Copyright (C) 1999-2012, Broadcom Corporation 58ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 6832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt * Unless you and Broadcom execute a separate written software license 78ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * agreement governing use of this software, this software is licensed to you 88ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * under the terms of the GNU General Public License version 2 (the "GPL"), 98ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * available at http://www.broadcom.com/licenses/GPLv2.php, with the 108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * following added to such license: 118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * As a special exception, the copyright holders of this software give you 138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * permission to link this software with independent modules, and to copy and 148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * distribute the resulting executable under terms of your choice, provided that 158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * you also meet, for each linked independent module, the terms and conditions of 168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * the license of that module. An independent module is a module which is not 178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * derived from this software. The special exception does not apply to any 188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * modifications of the software. 198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Notwithstanding the above, under no circumstances may you combine this 218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * software in any way with any other Broadcom software provided under a license 228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * other than the GPL, without Broadcom's express prior written consent. 238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 248f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt * $Id: bcmsdh_linux.c 347638 2012-07-27 11:39:03Z $ 258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/** 288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * @file bcmsdh_linux.c 298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define __UNDEF_NO_VERSION__ 328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <typedefs.h> 348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <linuxver.h> 358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <linux/pci.h> 378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <linux/completion.h> 388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <osl.h> 408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <pcicfg.h> 418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmdefs.h> 428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmdevs.h> 438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(OOB_INTR_ONLY) 458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <linux/irq.h> 468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern void dhdsdio_isr(void * args); 478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmutils.h> 488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <dngl_stats.h> 498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <dhd.h> 508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* defined(OOB_INTR_ONLY) */ 518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 528f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt 538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/** 548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * SDIO Host Controller info 558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidttypedef struct bcmsdh_hc bcmsdh_hc_t; 578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstruct bcmsdh_hc { 598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_hc_t *next; 608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMPLATFORM_BUS 618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt struct device *dev; /* platform device handle */ 628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else 638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt struct pci_dev *dev; /* pci device handle */ 648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_t *osh; 668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt void *regs; /* SDIO Host Controller address */ 678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ 688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt void *ch; 698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt unsigned int oob_irq; 708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt unsigned long oob_flags; /* OOB Host specifiction as edge and etc */ 718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bool oob_irq_registered; 728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bool oob_irq_enable_flag; 738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(OOB_INTR_ONLY) 748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt spinlock_t irq_lock; 758f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* defined(OOB_INTR_ONLY) */ 768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}; 778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic bcmsdh_hc_t *sdhcinfo = NULL; 788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* driver info, initialized when bcmsdh_register is called */ 808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic bcmsdh_driver_t drvinfo = {NULL, NULL}; 818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* debugging macros */ 838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define SDLX_MSG(x) 848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/** 868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Checks to see if vendor and device IDs match a supported SDIO Host Controller. 878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbool 898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmsdh_chipmatch(uint16 vendor, uint16 device) 908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Add other vendors and devices as required */ 928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMSDIOH_STD 948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Check for Arasan host controller */ 958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (vendor == VENDOR_SI_IMAGE) { 968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Check for BRCM 27XX Standard host controller */ 998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) { 1008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 1018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Check for BRCM Standard host controller */ 1038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) { 1048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 1058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Check for TI PCIxx21 Standard host controller */ 1078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) { 1088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 1098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) { 1118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 1128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Ricoh R5C822 Standard SDIO Host */ 1148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) { 1158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 1168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* JMicron Standard SDIO Host */ 1188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) { 1198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 1208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMSDIOH_STD */ 1238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMSDIOH_SPI 1248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* This is the PciSpiHost. */ 1258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { 1268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt printf("Found PCI SPI Host Controller\n"); 1278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (TRUE); 1288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMSDIOH_SPI */ 1318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (FALSE); 1338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 1348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(BCMPLATFORM_BUS) 1368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(BCMLXSDMMC) 1378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* forward declarations */ 1388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint bcmsdh_probe(struct device *dev); 1398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint bcmsdh_remove(struct device *dev); 1408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1418ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_probe); 1428ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_remove); 1438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else 1458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* forward declarations */ 1468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic int __devinit bcmsdh_probe(struct device *dev); 1478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic int __devexit bcmsdh_remove(struct device *dev); 1488f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* defined(BCMLXSDMMC) */ 1498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1508f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#if !defined(BCMLXSDMMC) 1518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic 1528f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* !defined(BCMLXSDMMC) */ 1538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint bcmsdh_probe(struct device *dev) 1548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 1558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_t *osh = NULL; 1568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_hc_t *sdhc = NULL; 1578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ulong regs = 0; 1588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_info_t *sdh = NULL; 1598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) 1608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt struct platform_device *pdev; 1618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt struct resource *r; 1628f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) */ 1638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt int irq = 0; 1648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt uint32 vendevid; 1658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt unsigned long irq_flags = 0; 1668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) 1688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt pdev = to_platform_device(dev); 1698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt irq = platform_get_irq(pdev, 0); 1718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!r || irq == NO_IRQ) 1728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -ENXIO; 1738f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) */ 1748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(OOB_INTR_ONLY) 1768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef HW_OOB 1778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt irq_flags = 1788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; 1798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else 1808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt irq_flags = IRQF_TRIGGER_FALLING; 1818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* HW_OOB */ 1828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */ 1848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt irq = dhd_customer_oob_irq_map(&irq_flags); 1858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (irq < 0) { 1868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__)); 1878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 1; 1888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* defined(OOB_INTR_ONLY) */ 1908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* allocate SDIO Host Controller state info */ 1918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) { 1928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 1938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 1948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { 1968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: out of memory, allocated %d bytes\n", 1978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt __FUNCTION__, 1988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt MALLOCED(osh))); 1998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 2008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bzero(sdhc, sizeof(bcmsdh_hc_t)); 2028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->osh = osh; 2038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->dev = (void *)dev; 2058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2068f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#if defined(BCMLXSDMMC) 2078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(sdh = bcmsdh_attach(osh, (void *)0, 2088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (void **)®s, irq))) { 2098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 2108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 2118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else 2138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(sdh = bcmsdh_attach(osh, (void *)r->start, 2148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (void **)®s, irq))) { 2158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 2168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 2178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2188f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* defined(BCMLXSDMMC) */ 2198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->sdh = sdh; 2208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->oob_irq = irq; 2218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->oob_flags = irq_flags; 2228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->oob_irq_registered = FALSE; /* to make sure.. */ 2238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->oob_irq_enable_flag = FALSE; 2248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(OOB_INTR_ONLY) 2258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt spin_lock_init(&sdhc->irq_lock); 2268f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* defined(BCMLXSDMMC) */ 2278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* chain SDIO Host Controller info together */ 2298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->next = sdhcinfo; 2308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo = sdhc; 2318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Read the vendor/device ID from the CIS */ 2338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt vendevid = bcmsdh_query_device(sdh); 2348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* try to attach to the target device */ 2358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(sdhc->ch = drvinfo.attach((vendevid >> 16), 2368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (vendevid & 0xFFFF), 0, 0, 0, 0, 2378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (void *)regs, NULL, sdh))) { 2388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); 2398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 2408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 2438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* error handling */ 2458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidterr: 2468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhc) { 2478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhc->sdh) 2488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 2498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 2508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (osh) 2528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_detach(osh); 2538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -ENODEV; 2548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 2558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2568f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#if !defined(BCMLXSDMMC) 2578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic 2588f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif /* !defined(BCMLXSDMMC) */ 2598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint bcmsdh_remove(struct device *dev) 2608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 2618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_hc_t *sdhc, *prev; 2628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_t *osh; 2638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc = sdhcinfo; 2658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt drvinfo.detach(sdhc->ch); 2668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 2678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* find the SDIO Host Controller state for this pdev and take it out from the list */ 2698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { 2708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhc->dev == (void *)dev) { 2718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (prev) 2728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt prev->next = sdhc->next; 2738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else 2748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo = NULL; 2758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt break; 2768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt prev = sdhc; 2788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!sdhc) { 2808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: failed\n", __FUNCTION__)); 2818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 2828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* release SDIO Host Controller info */ 2858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osh = sdhc->osh; 2868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 2878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_detach(osh); 2888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) 2908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt dev_set_drvdata(dev, NULL); 2918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) */ 2928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 2948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 2958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else /* BCMPLATFORM_BUS */ 2978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if !defined(BCMLXSDMMC) 2998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* forward declarations for PCI probe and remove functions. */ 3008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 3018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); 3028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/** 3048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * pci id table 3058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 3068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { 3078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt { vendor: PCI_ANY_ID, 3088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt device: PCI_ANY_ID, 3098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt subvendor: PCI_ANY_ID, 3108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt subdevice: PCI_ANY_ID, 3118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt class: 0, 3128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt class_mask: 0, 3138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt driver_data: 0, 3148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt }, 3158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt { 0, } 3168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt}; 3178ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtMODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); 3188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/** 3208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * SDIO Host Controller pci driver info 3218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 3228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic struct pci_driver bcmsdh_pci_driver = { 3238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt node: {}, 3248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt name: "bcmsdh", 3258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt id_table: bcmsdh_pci_devid, 3268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt probe: bcmsdh_pci_probe, 3278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt remove: bcmsdh_pci_remove, 3288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 3298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt save_state: NULL, 3308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 3318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt suspend: NULL, 3328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt resume: NULL, 3338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt }; 3348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_pci_slot; /* Force detection to a particular PCI */ 3378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* slot only . Allows for having multiple */ 3388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* WL devices at once in a PC */ 3398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Only one instance of dhd will be */ 3408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* usable at a time */ 3418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Upper word is bus number, */ 3428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* lower word is slot number */ 3438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Default value of 0xffffffff turns this */ 3448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* off */ 3458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_pci_slot, uint, 0); 3468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/** 3498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Detect supported SDIO Host Controller and attach if found. 3508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 3518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Determine if the device described by pdev is a supported SDIO Host 3528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Controller. If so, attach to it and attach to the target device. 3538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 3548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic int __devinit 3558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 3578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_t *osh = NULL; 3588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_hc_t *sdhc = NULL; 3598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ulong regs; 3608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_info_t *sdh = NULL; 3618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt int rc; 3628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sd_pci_slot != 0xFFFFffff) { 3648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (pdev->bus->number != (sd_pci_slot>>16) || 3658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) { 3668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n", 3678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt __FUNCTION__, 3688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_chipmatch(pdev->vendor, pdev->device) 3698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ?"Found compatible SDIOHC" 3708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt :"Probing unknown device", 3718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, 3728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt pdev->device)); 3738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -ENODEV; 3748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 3758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n", 3768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt __FUNCTION__, 3778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_chipmatch(pdev->vendor, pdev->device) 3788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ?"Using compatible SDIOHC" 3798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt :"WARNING, forced use of unkown device", 3808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device)); 3818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 3828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) || 3848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { 3858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt uint32 config_reg; 3868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__)); 3888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { 3898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 3908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 3918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 3928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); 3948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 3958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* 3968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Set MMC_SD_DIS bit in FlashMedia Controller. 3978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Disbling the SD/MMC Controller in the FlashMedia Controller 3988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * allows the Standard SD Host Controller to take over control 3998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * of the SD Slot. 4008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 4018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt config_reg |= 0x02; 4028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); 4038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_detach(osh); 4048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* match this pci device with what we support */ 4068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* we can't solely rely on this to believe it is our SDIO Host Controller! */ 4078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { 4088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -ENODEV; 4098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* this is a pci device we might support */ 4128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n", 4138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt __FUNCTION__, 4148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt pdev->bus->number, PCI_SLOT(pdev->devfn), 4158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt PCI_FUNC(pdev->devfn), pdev->irq)); 4168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* use bcmsdh_query_device() to get the vendor ID of the target device so 4188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * it will eventually appear in the Broadcom string on the console 4198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 4208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* allocate SDIO Host Controller state info */ 4228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { 4238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 4248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 4258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { 4278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: out of memory, allocated %d bytes\n", 4288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt __FUNCTION__, 4298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt MALLOCED(osh))); 4308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 4318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bzero(sdhc, sizeof(bcmsdh_hc_t)); 4338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->osh = osh; 4348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->dev = pdev; 4368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* map to address where host can access */ 4388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt pci_set_master(pdev); 4398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt rc = pci_enable_device(pdev); 4408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (rc) { 4418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: Cannot enable PCI device\n", __FUNCTION__)); 4428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 4438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0), 4458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (void **)®s, pdev->irq))) { 4468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 4478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 4488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->sdh = sdh; 4518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* try to attach to the target device */ 4538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ 4548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, 4558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (void *)regs, NULL, sdh))) { 4568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); 4578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto err; 4588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* chain SDIO Host Controller info together */ 4618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhc->next = sdhcinfo; 4628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo = sdhc; 4638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 4658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* error handling */ 4678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidterr: 4688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhc) { 4698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhc->sdh) 4708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 4718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 4728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (osh) 4748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_detach(osh); 4758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -ENODEV; 4768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 4778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/** 4808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Detach from target devices and SDIO Host Controller 4818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 4828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic void __devexit 4838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmsdh_pci_remove(struct pci_dev *pdev) 4848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 4858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_hc_t *sdhc, *prev; 4868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_t *osh; 4878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 4888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* find the SDIO Host Controller state for this pdev and take it out from the list */ 4898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { 4908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhc->dev == pdev) { 4918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (prev) 4928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt prev->next = sdhc->next; 4938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else 4948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo = NULL; 4958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt break; 4968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt prev = sdhc; 4988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 4998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!sdhc) 5008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return; 5018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt drvinfo.detach(sdhc->ch); 5038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 5058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* release SDIO Host Controller info */ 5078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osh = sdhc->osh; 5088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 5098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt osl_detach(osh); 5108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 5118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMLXSDMMC */ 5128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 5138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern int sdio_function_init(void); 5158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 516832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtextern int sdio_func_reg_notify(void* semaphore); 517832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtextern void sdio_func_unreg_notify(void); 518832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 5194a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#if defined(BCMLXSDMMC) 520832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtint bcmsdh_reg_sdio_notify(void* semaphore) 521832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 5224a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt return sdio_func_reg_notify(semaphore); 523832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 524832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 525832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtvoid bcmsdh_unreg_sdio_notify(void) 526832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 527832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sdio_func_unreg_notify(); 528832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 5294a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#endif /* defined(BCMLXSDMMC) */ 530832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 5318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint 5328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmsdh_register(bcmsdh_driver_t *driver) 5338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 5348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt int error = 0; 5358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt drvinfo = *driver; 5378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(BCMPLATFORM_BUS) 5398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); 5408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt error = sdio_function_init(); 5418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return error; 5428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* defined(BCMPLATFORM_BUS) */ 5438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) 5458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 5468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(error = pci_module_init(&bcmsdh_pci_driver))) 5478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 5488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else 5498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!(error = pci_register_driver(&bcmsdh_pci_driver))) 5508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 5518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 5528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error)); 5548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 5558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return error; 5578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 5588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern void sdio_function_cleanup(void); 5608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid 5628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbcmsdh_unregister(void) 5638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 5648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 5658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (bcmsdh_pci_driver.node.next) 5668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 5678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(BCMLXSDMMC) 5698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdio_function_cleanup(); 5708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMLXSDMMC */ 5718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) 5738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt pci_unregister_driver(&bcmsdh_pci_driver); 5748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 5758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 5768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(OOB_INTR_ONLY) 5788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid bcmsdh_oob_intr_set(bool enable) 5798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 5808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt static bool curstate = 1; 5818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt unsigned long flags; 5828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt spin_lock_irqsave(&sdhcinfo->irq_lock, flags); 5848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (curstate != enable) { 5858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (enable) 5868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt enable_irq(sdhcinfo->oob_irq); 5878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else 5888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt disable_irq_nosync(sdhcinfo->oob_irq); 5898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt curstate = enable; 5908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 5918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); 5928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 5938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtstatic irqreturn_t wlan_oob_irq(int irq, void *dev_id) 5958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 5968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt dhd_pub_t *dhdp; 5978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 5988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev); 5998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_oob_intr_set(0); 6018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (dhdp == NULL) { 6038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("Out of band GPIO interrupt fired way too early\n")); 6048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return IRQ_HANDLED; 6058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 6068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt dhdsdio_isr((void *)dhdp->bus); 6088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return IRQ_HANDLED; 6108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 6118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint bcmsdh_register_oob_intr(void * dhdp) 6138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 6148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt int error = 0; 6158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s Enter \n", __FUNCTION__)); 6178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */ 6198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt dev_set_drvdata(sdhcinfo->dev, dhdp); 6218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!sdhcinfo->oob_irq_registered) { 6238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, 6248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags)); 6258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt /* Refer to customer Host IRQ docs about proper irqflags definition */ 6268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags, 6278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt "bcmsdh_sdmmc", NULL); 6288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (error) 6298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -ENODEV; 6308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6318f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt error = enable_irq_wake(sdhcinfo->oob_irq); 6328f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt if (error) 6338f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt SDLX_MSG(("%s enable_irq_wake error=%d \n", __FUNCTION__, error)); 6348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo->oob_irq_registered = TRUE; 6358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo->oob_irq_enable_flag = TRUE; 6368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 6378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 6398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 6408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid bcmsdh_set_irq(int flag) 6428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 6438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) { 6448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag)); 6458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo->oob_irq_enable_flag = flag; 6468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (flag) { 6478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt enable_irq(sdhcinfo->oob_irq); 6488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt enable_irq_wake(sdhcinfo->oob_irq); 6498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 6508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt disable_irq_wake(sdhcinfo->oob_irq); 6518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt disable_irq(sdhcinfo->oob_irq); 6528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 6538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 6548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 6558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtvoid bcmsdh_unregister_oob_intr(void) 6578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 6588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt SDLX_MSG(("%s: Enter\n", __FUNCTION__)); 6598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (sdhcinfo->oob_irq_registered == TRUE) { 6618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bcmsdh_set_irq(FALSE); 6628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt free_irq(sdhcinfo->oob_irq, NULL); 6638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sdhcinfo->oob_irq_registered = FALSE; 6648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 6658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 6668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* defined(OOB_INTR_ONLY) */ 6678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6684a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#if defined(BCMLXSDMMC) 6694a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidtvoid *bcmsdh_get_drvdata(void) 6704a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt{ 6714a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt if (!sdhcinfo) 6724a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt return NULL; 6734a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt return dev_get_drvdata(sdhcinfo->dev); 6744a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt} 6754a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#endif 6764a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt 6778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* Module parameters specific to each host-controller driver */ 6788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_msglevel; /* Debug message level */ 6808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_msglevel, uint, 0); 6818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ 6838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_power, uint, 0); 6848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */ 6868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_clock, uint, 0); 6878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_divisor; /* Divisor (-1 means external clock) */ 6898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_divisor, uint, 0); 6908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ 6928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_sdmode, uint, 0); 6938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_hiok; /* Ok to use hi-speed mode */ 6958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_hiok, uint, 0); 6968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 6978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern uint sd_f2_blocksize; 6988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_f2_blocksize, int, 0); 6998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 7008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMSDIOH_STD 7018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtextern int sd_uhsimode; 7028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtmodule_param(sd_uhsimode, int, 0); 7038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 7048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 7058f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#ifdef BCMSDIOH_TXGLOM 7068f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidtextern uint sd_txglom; 7078f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidtmodule_param(sd_txglom, uint, 0); 7088f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt#endif 7098f237d3133b0672c337c27a1e34daad2b4e76f45Dmitry Shmidt 7108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMSDH_MODULE 7118ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_attach); 7128ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_detach); 7138ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_query); 7148ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_enable); 7158ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_disable); 7168ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_reg); 7178ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_dereg); 7188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 7198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(DHD_DEBUG) 7208ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_pending); 7218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 7228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 7238ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_devremove_reg); 7248ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_read); 7258ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_write); 7268ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cis_read); 7278ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_reg_read); 7288ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_reg_write); 7298ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_regfail); 7308ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_send_buf); 7318ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_recv_buf); 7328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 7338ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_rwdata); 7348ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_abort); 7358ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_query_device); 7368ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_query_iofnum); 7378ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_iovar_op); 7388ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_register); 7398ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_unregister); 7408ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_chipmatch); 7418ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_reset); 7428ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_waitlockfree); 7438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 7448ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_get_dstatus); 7458ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_read_word); 7468ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_write_word); 7478ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cur_sbwad); 7488ce1727333a1c411bb88330d69f82386a118c6bfDmitry ShmidtEXPORT_SYMBOL(bcmsdh_chipinfo); 7498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 7508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif /* BCMSDH_MODULE */ 751