14d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/* 24d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * SDIO access interface for drivers - linux specific (pci only) 34d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * 407770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman * Copyright (C) 1999-2010, Broadcom Corporation 54d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * 64d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Unless you and Broadcom execute a separate written software license 74d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * agreement governing use of this software, this software is licensed to you 84d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * under the terms of the GNU General Public License version 2 (the "GPL"), 94d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * available at http://www.broadcom.com/licenses/GPLv2.php, with the 104d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * following added to such license: 114d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * 124d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * As a special exception, the copyright holders of this software give you 134d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * permission to link this software with independent modules, and to copy and 144d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * distribute the resulting executable under terms of your choice, provided that 154d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * you also meet, for each linked independent module, the terms and conditions of 164d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * the license of that module. An independent module is a module which is not 174d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * derived from this software. The special exception does not apply to any 184d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * modifications of the software. 194d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * 204d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Notwithstanding the above, under no circumstances may you combine this 214d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * software in any way with any other Broadcom software provided under a license 224d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * other than the GPL, without Broadcom's express prior written consent. 234d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * 249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * $Id: bcmsdh_linux.c,v 1.42.10.10.2.14.4.2 2010/09/15 00:30:11 Exp $ 254d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 264d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 274d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/** 284d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * @file bcmsdh_linux.c 294d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 304d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 314d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#define __UNDEF_NO_VERSION__ 324d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 334d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <typedefs.h> 344d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <linuxver.h> 354d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 364d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <linux/pci.h> 374d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <linux/completion.h> 384d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 394d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <osl.h> 404d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <pcicfg.h> 414d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <bcmdefs.h> 424d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <bcmdevs.h> 434d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 44492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#if defined(OOB_INTR_ONLY) 45492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#include <linux/irq.h> 46492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidtextern void dhdsdio_isr(void * args); 47492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#include <bcmutils.h> 48492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#include <dngl_stats.h> 49492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#include <dhd.h> 50492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#endif /* defined(OOB_INTR_ONLY) */ 514d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270) 524d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if !defined(BCMPLATFORM_BUS) 534d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#define BCMPLATFORM_BUS 544d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* !defined(BCMPLATFORM_BUS) */ 554d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 564d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) 574d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#include <linux/platform_device.h> 584d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* KERNEL_VERSION(2, 6, 19) */ 594d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* CONFIG_MACH_SANDGATE2G || CONFIG_MACH_LOGICPD_PXA270 */ 604d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 614d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/** 624d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * SDIO Host Controller info 634d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 644d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidttypedef struct bcmsdh_hc bcmsdh_hc_t; 654d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 664d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstruct bcmsdh_hc { 674d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_hc_t *next; 684d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifdef BCMPLATFORM_BUS 694d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt struct device *dev; /* platform device handle */ 704d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#else 714d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt struct pci_dev *dev; /* pci device handle */ 724d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 734d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_t *osh; 744d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt void *regs; /* SDIO Host Controller address */ 754d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ 764d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt void *ch; 77492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt unsigned int oob_irq; 789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt unsigned long oob_flags; /* OOB Host specifiction as edge and etc */ 799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt bool oob_irq_registered; 809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if defined(OOB_INTR_ONLY) 819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt spinlock_t irq_lock; 829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif 834d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt}; 844d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic bcmsdh_hc_t *sdhcinfo = NULL; 854d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 864d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/* driver info, initialized when bcmsdh_register is called */ 874d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic bcmsdh_driver_t drvinfo = {NULL, NULL}; 884d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 894d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/* debugging macros */ 904d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#define SDLX_MSG(x) 914d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 924d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/** 934d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Checks to see if vendor and device IDs match a supported SDIO Host Controller. 944d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 954d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtbool 964d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtbcmsdh_chipmatch(uint16 vendor, uint16 device) 974d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt{ 984d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* Add other vendors and devices as required */ 994d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1004d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifdef BCMSDIOH_STD 1014d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* Check for Arasan host controller */ 1024d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (vendor == VENDOR_SI_IMAGE) { 1034d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1044d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1054d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* Check for BRCM 27XX Standard host controller */ 1064d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) { 1074d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1084d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1094d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* Check for BRCM Standard host controller */ 1104d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) { 1114d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1124d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1134d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* Check for TI PCIxx21 Standard host controller */ 1144d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) { 1154d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1164d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1174d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) { 1184d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1194d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1204d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* Ricoh R5C822 Standard SDIO Host */ 1214d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) { 1224d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1234d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1244d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* JMicron Standard SDIO Host */ 1254d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) { 1264d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1274d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1284d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1294d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMSDIOH_STD */ 1304d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifdef BCMSDIOH_SPI 1314d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* This is the PciSpiHost. */ 1324d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { 1334d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt printf("Found PCI SPI Host Controller\n"); 1344d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (TRUE); 1354d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 1364d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1374d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMSDIOH_SPI */ 1384d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1394d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return (FALSE); 1404d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt} 1414d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1424d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(BCMPLATFORM_BUS) 1434d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(BCMLXSDMMC) 1444d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/* forward declarations */ 1454d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtint bcmsdh_probe(struct device *dev); 1464d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtint bcmsdh_remove(struct device *dev); 1474d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1484d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_probe); 1494d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_remove); 1504d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1514d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#else 1524d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/* forward declarations */ 1534d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic int __devinit bcmsdh_probe(struct device *dev); 1544d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic int __devexit bcmsdh_remove(struct device *dev); 1554d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 1564d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1574d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifndef BCMLXSDMMC 1584d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic struct device_driver bcmsdh_driver = { 1594d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt .name = "pxa2xx-mci", 1604d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt .bus = &platform_bus_type, 1614d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt .probe = bcmsdh_probe, 1624d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt .remove = bcmsdh_remove, 1634d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt .suspend = NULL, 1644d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt .resume = NULL, 1654d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt }; 1664d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 1674d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1684d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifndef BCMLXSDMMC 1694d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic 1704d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 1714d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtint bcmsdh_probe(struct device *dev) 1724d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt{ 1734d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_t *osh = NULL; 1744d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_hc_t *sdhc = NULL; 1754d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt ulong regs = 0; 1764d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_info_t *sdh = NULL; 1774d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) 1784d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt struct platform_device *pdev; 1794d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt struct resource *r; 1804d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 1814d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt int irq = 0; 1824d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt uint32 vendevid; 1839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt unsigned long irq_flags = 0; 1844d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 1854d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) 1864d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt pdev = to_platform_device(dev); 1874d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1884d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt irq = platform_get_irq(pdev, 0); 1894d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!r || irq == NO_IRQ) 1904d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return -ENXIO; 1914d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 1924d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 193492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#if defined(OOB_INTR_ONLY) 1949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef HW_OOB 1959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt irq_flags = \ 1969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; 1979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else 1989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt irq_flags = IRQF_TRIGGER_FALLING; 1999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* HW_OOB */ 2009b66717d9e4dd32e61a03f572d4eaebbfb4ee6c3Dmitry Shmidt irq = dhd_customer_oob_irq_map(&irq_flags); 201492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt if (irq < 0) { 202492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__)); 203492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt return 1; 204492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt } 205492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#endif /* defined(OOB_INTR_ONLY) */ 2064d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* allocate SDIO Host Controller state info */ 2074d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) { 2084d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 2094d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 2104d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2114d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { 2124d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: out of memory, allocated %d bytes\n", 2134d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt __FUNCTION__, 2144d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt MALLOCED(osh))); 2154d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 2164d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2174d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bzero(sdhc, sizeof(bcmsdh_hc_t)); 2184d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhc->osh = osh; 2194d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2204d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhc->dev = (void *)dev; 2214d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2224d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifdef BCMLXSDMMC 2234d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(sdh = bcmsdh_attach(osh, (void *)0, 2244d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt (void **)®s, irq))) { 2254d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 2264d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 2274d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2284d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#else 2294d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(sdh = bcmsdh_attach(osh, (void *)r->start, 2304d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt (void **)®s, irq))) { 2314d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 2324d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 2334d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2344d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 2354d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhc->sdh = sdh; 236492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt sdhc->oob_irq = irq; 2379b66717d9e4dd32e61a03f572d4eaebbfb4ee6c3Dmitry Shmidt sdhc->oob_flags = irq_flags; 2389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt sdhc->oob_irq_registered = FALSE; /* to make sure.. */ 2399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if defined(OOB_INTR_ONLY) 2409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt spin_lock_init(&sdhc->irq_lock); 2419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif 2424d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 243492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt /* chain SDIO Host Controller info together */ 244492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt sdhc->next = sdhcinfo; 245492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt sdhcinfo = sdhc; 2464d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* Read the vendor/device ID from the CIS */ 2474d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt vendevid = bcmsdh_query_device(sdh); 2484d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2494d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* try to attach to the target device */ 2504d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(sdhc->ch = drvinfo.attach((vendevid >> 16), 2514d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt (vendevid & 0xFFFF), 0, 0, 0, 0, 2524d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt (void *)regs, NULL, sdh))) { 2534d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); 2544d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 2554d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2564d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2574d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return 0; 2584d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2594d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* error handling */ 2604d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidterr: 2614d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (sdhc) { 2624d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (sdhc->sdh) 2634d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 2644d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 2654d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2664d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (osh) 2674d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_detach(osh); 2684d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return -ENODEV; 2694d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt} 2704d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2714d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifndef BCMLXSDMMC 2724d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic 2734d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 2744d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtint bcmsdh_remove(struct device *dev) 2754d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt{ 2764d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_hc_t *sdhc, *prev; 2774d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_t *osh; 2784d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 279492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt sdhc = sdhcinfo; 280492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt drvinfo.detach(sdhc->ch); 281492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 2824d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* find the SDIO Host Controller state for this pdev and take it out from the list */ 2834d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { 2844d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (sdhc->dev == (void *)dev) { 2854d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (prev) 2864d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt prev->next = sdhc->next; 2874d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt else 2884d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhcinfo = NULL; 2894d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt break; 2904d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2914d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt prev = sdhc; 2924d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2934d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!sdhc) { 2944d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: failed\n", __FUNCTION__)); 2954d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return 0; 2964d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 2974d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2984d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 2994d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* release SDIO Host Controller info */ 3004d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osh = sdhc->osh; 3014d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 3024d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_detach(osh); 3034d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 3044d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if !defined(BCMLXSDMMC) 3054d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt dev_set_drvdata(dev, NULL); 3064d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* !defined(BCMLXSDMMC) */ 3074d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 3084d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return 0; 3094d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt} 3104d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 3114d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#else /* BCMPLATFORM_BUS */ 3124d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 3134d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if !defined(BCMLXSDMMC) 3144d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/* forward declarations for PCI probe and remove functions. */ 3154d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 3164d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); 3174d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 3184d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/** 3194d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * pci id table 3204d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 3214d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { 3224d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt { vendor: PCI_ANY_ID, 3234d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt device: PCI_ANY_ID, 3244d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt subvendor: PCI_ANY_ID, 3254d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt subdevice: PCI_ANY_ID, 3264d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt class: 0, 3274d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt class_mask: 0, 3284d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt driver_data: 0, 3294d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt }, 3304d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt { 0, } 3314d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt}; 3324d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtMODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); 3334d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 3344d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/** 3354d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * SDIO Host Controller pci driver info 3364d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 3374d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic struct pci_driver bcmsdh_pci_driver = { 3384d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt node: {}, 3394d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt name: "bcmsdh", 3404d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt id_table: bcmsdh_pci_devid, 3414d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt probe: bcmsdh_pci_probe, 3424d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt remove: bcmsdh_pci_remove, 3434d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 3444d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt save_state: NULL, 3454d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif 3464d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt suspend: NULL, 3474d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt resume: NULL, 3481a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt}; 3494d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 3504d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 35107770aa679cd45674eaac3d8fb2e01a995068838Greg Goldmanextern uint sd_pci_slot; /* Force detection to a particular PCI */ 3521a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt /* slot only . Allows for having multiple */ 3531a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt /* WL devices at once in a PC */ 3541a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt /* Only one instance of dhd will be */ 3559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt /* usable at a time */ 3561a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt /* Upper word is bus number, */ 3571a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt /* lower word is slot number */ 3581a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt /* Default value of 0xFFFFffff turns this */ 3591a9040ebea203168187d4e8f55cd5566a8eace4cDmitry Shmidt /* off */ 36007770aa679cd45674eaac3d8fb2e01a995068838Greg Goldmanmodule_param(sd_pci_slot, uint, 0); 36107770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman 36207770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman 3634d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/** 3644d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Detect supported SDIO Host Controller and attach if found. 3654d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * 3664d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Determine if the device described by pdev is a supported SDIO Host 3674d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Controller. If so, attach to it and attach to the target device. 3684d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 3694d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic int __devinit 3704d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtbcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3714d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt{ 3724d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_t *osh = NULL; 3734d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_hc_t *sdhc = NULL; 3744d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt ulong regs; 3754d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_info_t *sdh = NULL; 3764d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt int rc; 3774d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 37807770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman if (sd_pci_slot != 0xFFFFffff) { 37907770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman if (pdev->bus->number != (sd_pci_slot>>16) || 38007770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) { 38107770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n", 3829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt __FUNCTION__, 3839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt bcmsdh_chipmatch(pdev->vendor, pdev->device) ? 3849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt "Found compatible SDIOHC" : 3859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt "Probing unknown device", 3869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt pdev->bus->number, PCI_SLOT(pdev->devfn), 3879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt pdev->vendor, pdev->device)); 38807770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman return -ENODEV; 38907770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman } 39007770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n", 3919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt __FUNCTION__, 3929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt bcmsdh_chipmatch(pdev->vendor, pdev->device) ? 3939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt "Using compatible SDIOHC" : 3949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt "WARNING, forced use of unkown device", 3959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt pdev->bus->number, PCI_SLOT(pdev->devfn), 3969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt pdev->vendor, pdev->device)); 39707770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman } 39807770aa679cd45674eaac3d8fb2e01a995068838Greg Goldman 3994d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) || 4004d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { 4014d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt uint32 config_reg; 4024d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4034d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__)); 4044d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { 4054d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 4064d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 4074d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4084d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4094d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); 4104d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4114d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* 4124d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Set MMC_SD_DIS bit in FlashMedia Controller. 4134d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Disbling the SD/MMC Controller in the FlashMedia Controller 4144d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * allows the Standard SD Host Controller to take over control 4154d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * of the SD Slot. 4164d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 4174d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt config_reg |= 0x02; 4184d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); 4194d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_detach(osh); 4204d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4214d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* match this pci device with what we support */ 4224d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* we can't solely rely on this to believe it is our SDIO Host Controller! */ 4234d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { 4244d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return -ENODEV; 4254d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4264d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4274d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* this is a pci device we might support */ 4284d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n", 4294d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt __FUNCTION__, 4304d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt pdev->bus->number, PCI_SLOT(pdev->devfn), 4314d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt PCI_FUNC(pdev->devfn), pdev->irq)); 4324d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4334d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* use bcmsdh_query_device() to get the vendor ID of the target device so 4344d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * it will eventually appear in the Broadcom string on the console 4354d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 4364d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4374d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* allocate SDIO Host Controller state info */ 4384d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { 4394d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: osl_attach failed\n", __FUNCTION__)); 4404d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 4414d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4424d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { 4434d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: out of memory, allocated %d bytes\n", 4444d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt __FUNCTION__, 4454d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt MALLOCED(osh))); 4464d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 4474d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4484d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bzero(sdhc, sizeof(bcmsdh_hc_t)); 4494d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhc->osh = osh; 4504d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4514d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhc->dev = pdev; 4524d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4534d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* map to address where host can access */ 4544d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt pci_set_master(pdev); 4554d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt rc = pci_enable_device(pdev); 4564d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (rc) { 4579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt SDLX_MSG(("%s: Cannot enable PCI device\n", __FUNCTION__)); 4584d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 4594d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4604d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0), 4614d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt (void **)®s, pdev->irq))) { 4624d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: bcmsdh_attach failed\n", __FUNCTION__)); 4634d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 4644d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4654d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4664d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhc->sdh = sdh; 4674d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4684d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* try to attach to the target device */ 4694d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ 4704d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, 4714d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt (void *)regs, NULL, sdh))) { 4724d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: device attach failed\n", __FUNCTION__)); 4734d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt goto err; 4744d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 4754d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4764d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* chain SDIO Host Controller info together */ 4774d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhc->next = sdhcinfo; 4784d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhcinfo = sdhc; 4794d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4804d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return 0; 4814d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4824d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* error handling */ 4834d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidterr: 4844d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (sdhc->sdh) 4854d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 4864d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (sdhc) 4874d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 4884d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (osh) 4894d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_detach(osh); 4904d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return -ENODEV; 4914d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt} 4924d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4934d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 4944d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/** 4954d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt * Detach from target devices and SDIO Host Controller 4964d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt */ 4974d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtstatic void __devexit 4984d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtbcmsdh_pci_remove(struct pci_dev *pdev) 4994d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt{ 5004d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_hc_t *sdhc, *prev; 5014d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_t *osh; 5024d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5034d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* find the SDIO Host Controller state for this pdev and take it out from the list */ 5044d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { 5054d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (sdhc->dev == pdev) { 5064d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (prev) 5074d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt prev->next = sdhc->next; 5084d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt else 5094d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdhcinfo = NULL; 5104d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt break; 5114d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 5124d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt prev = sdhc; 5134d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt } 5144d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!sdhc) 5154d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return; 5164d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5174d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt drvinfo.detach(sdhc->ch); 5184d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5194d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt bcmsdh_detach(sdhc->osh, sdhc->sdh); 5204d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5214d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt /* release SDIO Host Controller info */ 5224d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osh = sdhc->osh; 5234d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); 5244d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt osl_detach(osh); 5254d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt} 5264d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 5274d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 5284d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5294d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern int sdio_function_init(void); 5304d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5314d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtint 5324d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtbcmsdh_register(bcmsdh_driver_t *driver) 5334d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt{ 5344d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt int error = 0; 5354d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5364d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt drvinfo = *driver; 5374d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5384d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(BCMPLATFORM_BUS) 5394d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(BCMLXSDMMC) 5404d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); 5414d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt error = sdio_function_init(); 5424d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#else 5434d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("Intel PXA270 SDIO Driver\n")); 5444d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt error = driver_register(&bcmsdh_driver); 5454d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* defined(BCMLXSDMMC) */ 5464d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return error; 5474d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* defined(BCMPLATFORM_BUS) */ 5484d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5494d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) 5504d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 5514d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(error = pci_module_init(&bcmsdh_pci_driver))) 5524d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return 0; 5534d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#else 5544d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (!(error = pci_register_driver(&bcmsdh_pci_driver))) 5554d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return 0; 5564d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif 5574d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5584d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt SDLX_MSG(("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error)); 5594d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 5604d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5614d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt return error; 5624d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt} 5634d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5644d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern void sdio_function_cleanup(void); 5654d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5664d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtvoid 5674d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtbcmsdh_unregister(void) 5684d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt{ 5694d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) 5704d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt if (bcmsdh_pci_driver.node.next) 5714d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif 5724d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5734d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) 5744d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt driver_unregister(&bcmsdh_driver); 5754d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif 5764d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(BCMLXSDMMC) 5774d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt sdio_function_cleanup(); 5784d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMLXSDMMC */ 5794d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) 5804d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt pci_unregister_driver(&bcmsdh_pci_driver); 5814d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMPLATFORM_BUS */ 5824d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt} 5834d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 5849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt 5859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt 586492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#if defined(OOB_INTR_ONLY) 5879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtvoid bcmsdh_oob_intr_set(bool enable) 5889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{ 5899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt static bool curstate = 1; 5909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt unsigned long flags; 5919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt 5929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt spin_lock_irqsave(&sdhcinfo->irq_lock, flags); 5939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt if (curstate != enable) { 5949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt if (enable) 5959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt enable_irq(sdhcinfo->oob_irq); 5969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt else 5979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt disable_irq_nosync(sdhcinfo->oob_irq); 5989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt curstate = enable; 5999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt } 6009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); 6019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt} 6029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt 603492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidtstatic irqreturn_t wlan_oob_irq(int irq, void *dev_id) 604492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt{ 605492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt dhd_pub_t *dhdp; 606492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 607a05cf6aee61444a6f415731b3c1e9529904da85dDmitry Shmidt dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev); 608492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 6099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt bcmsdh_oob_intr_set(0); 6109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt 611492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt if (dhdp == NULL) { 612492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt SDLX_MSG(("Out of band GPIO interrupt fired way too early\n")); 613492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt return IRQ_HANDLED; 614492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt } 615492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 616492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt dhdsdio_isr((void *)dhdp->bus); 617492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 618492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt return IRQ_HANDLED; 619492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt} 620492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 621492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidtint bcmsdh_register_oob_intr(void * dhdp) 622492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt{ 623492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt int error = 0; 624492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 625492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt SDLX_MSG(("%s Enter\n", __FUNCTION__)); 626492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 627a05cf6aee61444a6f415731b3c1e9529904da85dDmitry Shmidt dev_set_drvdata(sdhcinfo->dev, dhdp); 628492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 6299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt if (!sdhcinfo->oob_irq_registered) { 6309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, \ 6319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags)); 6329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt /* Refer to customer Host IRQ docs about proper irqflags definition */ 6339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags, 6349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt "bcmsdh_sdmmc", NULL); 6359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt if (error) 6369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt return -ENODEV; 637492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 6389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt set_irq_wake(sdhcinfo->oob_irq, 1); 6399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt sdhcinfo->oob_irq_registered = TRUE; 6409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt } 6419b66717d9e4dd32e61a03f572d4eaebbfb4ee6c3Dmitry Shmidt 642492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt return 0; 643492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt} 644492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 645492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidtvoid bcmsdh_unregister_oob_intr(void) 646492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt{ 647492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt SDLX_MSG(("%s: Enter\n", __FUNCTION__)); 648492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt 649492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt set_irq_wake(sdhcinfo->oob_irq, 0); 650492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt disable_irq(sdhcinfo->oob_irq); /* just in case.. */ 651492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt free_irq(sdhcinfo->oob_irq, NULL); 6529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt sdhcinfo->oob_irq_registered = FALSE; 653492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt} 654492884be0b302c6c6ea51b360c1f7b0996d96a8bDmitry Shmidt#endif /* defined(OOB_INTR_ONLY) */ 6554d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt/* Module parameters specific to each host-controller driver */ 6564d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6574d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern uint sd_msglevel; /* Debug message level */ 6584d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtmodule_param(sd_msglevel, uint, 0); 6594d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6604d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ 6614d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtmodule_param(sd_power, uint, 0); 6624d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6634d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */ 6644d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtmodule_param(sd_clock, uint, 0); 6654d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6664d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern uint sd_divisor; /* Divisor (-1 means external clock) */ 6674d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtmodule_param(sd_divisor, uint, 0); 6684d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6694d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ 6704d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtmodule_param(sd_sdmode, uint, 0); 6714d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6724d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern uint sd_hiok; /* Ok to use hi-speed mode */ 6734d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtmodule_param(sd_hiok, uint, 0); 6744d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6754d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtextern uint sd_f2_blocksize; 6764d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidtmodule_param(sd_f2_blocksize, int, 0); 6774d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6784d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6794d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#ifdef BCMSDH_MODULE 6804d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_attach); 6814d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_detach); 6824d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_query); 6834d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_enable); 6844d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_disable); 6854d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_reg); 6864d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_dereg); 6874d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6884d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#if defined(DHD_DEBUG) 6894d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_intr_pending); 6904d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif 6914d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 6924d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_devremove_reg); 6934d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_read); 6944d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_write); 6954d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cis_read); 6964d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_reg_read); 6974d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_reg_write); 6984d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_regfail); 6994d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_send_buf); 7004d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_recv_buf); 7014d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 7024d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_rwdata); 7034d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_abort); 7044d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_query_device); 7054d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_query_iofnum); 7064d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_iovar_op); 7074d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_register); 7084d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_unregister); 7094d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_chipmatch); 7104d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_reset); 7114d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 7124d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_get_dstatus); 7134d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_read_word); 7144d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cfg_write_word); 7154d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_cur_sbwad); 7164d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry ShmidtEXPORT_SYMBOL(bcmsdh_chipinfo); 7174d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt 7184d92e4c7da35860a39214c8fdb794ce0243dfabbDmitry Shmidt#endif /* BCMSDH_MODULE */ 719