len, set);
}
-int brcmf_sdcard_intr_enable(struct brcmf_sdio_dev *sdiodev)
-{
- return brcmf_sdioh_interrupt_set(sdiodev->sdioh, true);
-}
-
-int brcmf_sdcard_intr_disable(struct brcmf_sdio_dev *sdiodev)
-{
- return brcmf_sdioh_interrupt_set(sdiodev->sdioh, false);
-}
-
int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev,
void (*fn)(void *), void *argh)
{
#include "dhd_dbg.h"
#include "wl_cfg80211.h"
-#define CLIENT_INTR 0x100 /* Get rid of this! */
-
#if !defined(SDIO_VENDOR_ID_BROADCOM)
#define SDIO_VENDOR_ID_BROADCOM 0x02d0
#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
-struct sdos_info {
- struct sdioh_info *sd;
- spinlock_t lock;
-};
-
static void brcmf_sdioh_irqhandler(struct sdio_func *func);
static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func);
static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr);
BRCMF_ERROR(("sdioh_attach: out of memory\n"));
return NULL;
}
- if (brcmf_sdioh_osinit(sd) != 0) {
- BRCMF_ERROR(("%s:sdioh_sdmmc_osinit() failed\n", __func__));
- kfree(sd);
- return NULL;
- }
sd->num_funcs = 2;
- sd->use_client_ints = true;
sd->client_block_size[0] = 64;
gInstance->sd = sd;
sdio_disable_func(gInstance->func[1]);
sdio_release_host(gInstance->func[1]);
- /* deregister irq */
- brcmf_sdioh_osfree(sd);
-
kfree(sd);
}
return 0;
enum {
IOV_MSGLEVEL = 1,
IOV_BLOCKSIZE,
- IOV_USEINTS,
IOV_NUMINTS,
IOV_DEVREG,
IOV_HCIREGS,
const struct brcmu_iovar sdioh_iovars[] = {
{"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0},/* ((fn << 16) |
size) */
- {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0},
{"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0},
{"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)}
,
memcpy(arg, &int_val, val_size);
break;
- case IOV_GVAL(IOV_USEINTS):
- int_val = (s32) si->use_client_ints;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_USEINTS):
- si->use_client_ints = (bool) int_val;
- if (si->use_client_ints)
- si->intmask |= CLIENT_INTR;
- else
- si->intmask &= ~CLIENT_INTR;
-
- break;
-
case IOV_GVAL(IOV_NUMINTS):
int_val = (s32) si->intrcount;
memcpy(arg, &int_val, val_size);
return 0;
}
-/* Disable device interrupt */
-void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd)
-{
- BRCMF_TRACE(("%s: %d\n", __func__, sd->use_client_ints));
- sd->intmask &= ~CLIENT_INTR;
-}
-
-/* Enable device interrupt */
-void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd)
-{
- BRCMF_TRACE(("%s: %d\n", __func__, sd->use_client_ints));
- sd->intmask |= CLIENT_INTR;
-}
-
/* Read client card reg */
int
brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr,
sdio_release_host(gInstance->func[0]);
- if (sd->use_client_ints) {
- sd->intrcount++;
- (sd->intr_handler) (sd->intr_handler_arg);
- } else {
- BRCMF_ERROR(("brcmf: ***IRQHandler\n"));
-
- BRCMF_ERROR(("%s: Not ready for intr: enabled %d, handler %p\n",
- __func__, sd->client_intr_enabled, sd->intr_handler));
- }
+ sd->intrcount++;
+ (sd->intr_handler) (sd->intr_handler_arg);
sdio_claim_host(gInstance->func[0]);
}
}
#endif /* CONFIG_PM_SLEEP */
-int brcmf_sdioh_osinit(struct sdioh_info *sd)
-{
- struct sdos_info *sdos;
-
- sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC);
- sd->sdos_info = (void *)sdos;
- if (sdos == NULL)
- return -ENOMEM;
-
- sdos->sd = sd;
- spin_lock_init(&sdos->lock);
- return 0;
-}
-
-void brcmf_sdioh_osfree(struct sdioh_info *sd)
-{
- struct sdos_info *sdos;
-
- sdos = (struct sdos_info *)sd->sdos_info;
- kfree(sdos);
-}
-
-/* Interrupt enable/disable */
-int brcmf_sdioh_interrupt_set(struct sdioh_info *sd, bool enable)
-{
- unsigned long flags;
- struct sdos_info *sdos;
-
- BRCMF_TRACE(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling"));
-
- sdos = (struct sdos_info *)sd->sdos_info;
-
- if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
- BRCMF_ERROR(("%s: no handler registered, will not enable\n",
- __func__));
- return -EINVAL;
- }
-
- /* Ensure atomicity for enable/disable calls */
- spin_lock_irqsave(&sdos->lock, flags);
-
- sd->client_intr_enabled = enable;
- if (enable)
- brcmf_sdioh_dev_intr_on(sd);
- else
- brcmf_sdioh_dev_intr_off(sd);
-
- spin_unlock_irqrestore(&sdos->lock, flags);
-
- return 0;
-}
-
/*
* module init
*/
bool intr; /* Use interrupts */
bool poll; /* Use polling */
bool ipend; /* Device interrupt is pending */
- bool intdis; /* Interrupts disabled by isr */
uint intrcount; /* Count of device interrupt callbacks */
uint lastintrs; /* Count as of last watchdog timer */
uint spurious; /* Count of spurious interrupts */
if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
return -EBUSY;
- /* Disable SDIO interrupts (no longer interested) */
- brcmf_sdcard_intr_disable(bus->sdiodev);
-
/* Make sure the controller has the bus up */
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
/* Change state */
bus->sleeping = false;
-
- /* Enable interrupts again */
- if (bus->intr && (bus->drvr->busstate == BRCMF_BUS_DATA)) {
- bus->intdis = false;
- brcmf_sdcard_intr_enable(bus->sdiodev);
- }
}
return 0;
case IOV_SVAL(IOV_INTR):
bus->intr = bool_val;
- bus->intdis = false;
- if (bus->drvr->up) {
- BRCMF_INTR(("%s: %s SDIO interrupts\n", __func__,
- bus->intr ? "enable" : "disable"));
- if (bus->intr)
- brcmf_sdcard_intr_enable(bus->sdiodev);
- else
- brcmf_sdcard_intr_disable(bus->sdiodev);
- }
break;
case IOV_GVAL(IOV_POLLRATE):
/* Turn off the bus (F2), free any pending packets */
BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__));
- brcmf_sdcard_intr_disable(bus->sdiodev);
brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
SDIO_FUNC_ENABLE_1, NULL);
/* Set bus state according to enable result */
drvr->busstate = BRCMF_BUS_DATA;
-
- bus->intdis = false;
- if (bus->intr) {
- BRCMF_INTR(("%s: enable SDIO device interrupts\n",
- __func__));
- brcmf_sdcard_intr_enable(bus->sdiodev);
- } else {
- BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__));
- brcmf_sdcard_intr_disable(bus->sdiodev);
- }
-
}
else {
bus->intstatus = intstatus;
clkwait:
- /* Re-enable interrupts to detect new device events (mailbox, rx frame)
- * or clock availability. (Allows tx loop to check ipend if desired.)
- * (Unless register access seems hosed, as we may not be able to ACK...)
- */
- if (bus->intr && bus->intdis && !brcmf_sdcard_regfail(bus->sdiodev)) {
- BRCMF_INTR(("%s: enable SDIO interrupts, rxdone %d"
- " framecnt %d\n", __func__, rxdone, framecnt));
- bus->intdis = false;
- brcmf_sdcard_intr_enable(bus->sdiodev);
- }
-
if (DATAOK(bus) && bus->ctrl_frame_stat &&
(bus->clkstate == CLK_AVAIL)) {
int ret, i;
}
/* Disable additional interrupts (is this needed now)? */
- if (bus->intr)
- BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__));
- else
+ if (!bus->intr)
BRCMF_ERROR(("brcmf_sdbrcm_isr() w/o interrupt configured!\n"));
- brcmf_sdcard_intr_disable(bus->sdiodev);
- bus->intdis = true;
-
#if defined(SDIO_ISR_THREAD)
BRCMF_TRACE(("Calling brcmf_sdbrcm_dpc() from %s\n", __func__));
while (brcmf_sdbrcm_dpc(bus))
if (intstatus) {
bus->pollcnt++;
bus->ipend = true;
- if (bus->intr)
- brcmf_sdcard_intr_disable(bus->sdiodev);
bus->dpc_sched = true;
brcmf_sdbrcm_sched_dpc(bus);
/* Register interrupt callback, but mask it (not operational yet). */
BRCMF_INTR(("%s: disable SDIO interrupts (not interested yet)\n",
__func__));
- brcmf_sdcard_intr_disable(bus->sdiodev);
ret = brcmf_sdcard_intr_reg(bus->sdiodev, brcmf_sdbrcm_isr, bus);
if (ret != 0) {
BRCMF_ERROR(("%s: FAILED: sdcard_intr_reg returned %d\n",
if (bus) {
/* De-register interrupt handler */
- brcmf_sdcard_intr_disable(bus->sdiodev);
brcmf_sdcard_intr_dereg(bus->sdiodev);
if (bus->drvr) {
struct sdioh_info {
struct osl_info *osh; /* osh handler */
- bool client_intr_enabled; /* interrupt connnected flag */
bool intr_handler_valid; /* client driver interrupt handler valid */
void (*intr_handler)(void *); /* registered interrupt handler */
void *intr_handler_arg; /* argument to call interrupt handler */
- u16 intmask; /* Current active interrupts */
- void *sdos_info; /* Pointer to per-OS private data */
uint irq; /* Client irq */
int intrcount; /* Client interrupts */
bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */
/* Must be on for sd_multiblock to be effective */
- bool use_client_ints; /* If this is false, make sure to restore */
int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
u8 num_funcs; /* Supported funcs on client */
u32 com_cis_ptr;
void *bus;
};
-/* Enable/disable SD interrupt */
-extern int brcmf_sdcard_intr_enable(struct brcmf_sdio_dev *sdiodev);
-extern int brcmf_sdcard_intr_disable(struct brcmf_sdio_dev *sdiodev);
-
/* Register/deregister device interrupt handler. */
extern int
brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev,
/* Function to return current window addr */
extern u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_dev *sdiodev);
-/* Allocate/init/free per-OS private data */
-extern int brcmf_sdioh_osinit(struct sdioh_info *sd);
-extern void brcmf_sdioh_osfree(struct sdioh_info *sd);
-
-/* Core interrupt enable/disable of device interrupts */
-extern void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd);
-extern void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd);
-
/* attach, return handler on success, NULL if failed.
* The handler shall be provided by all subsequent calls. No local cache
* cfghdl points to the starting address of pci device mapped memory
extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *si);
-/* enable or disable SD interrupt */
-extern int
-brcmf_sdioh_interrupt_set(struct sdioh_info *si, bool enable_disable);
-
/* read or write one byte using cmd52 */
extern int
brcmf_sdioh_request_byte(struct sdioh_info *si, uint rw, uint fnc, uint addr,