/**
 *  @brief This function handles the interrupt.
 *
 *  @param func  A pointer to sdio_func structure
 *  @return      N/A
 */
static void
sd_interrupt(struct sdio_func *func)
{
	bt_private *priv;
	struct m_dev *m_dev = NULL;
	struct sdio_mmc_card *card;
	int ret = BT_STATUS_SUCCESS;
	u8 ireg = 0;
	u8 host_intstatus_reg = HOST_INTSTATUS_REG;

	ENTER();

	card = sdio_get_drvdata(func);
	if (!card || !card->priv) {
		PRINTM(INFO,
		       "BT: %s: sbi_interrupt(%p) card or priv is NULL, card=%p\n",
		       __func__, func, card);
		LEAVE();
		return;
	}
	priv = card->priv;
	m_dev = &(priv->bt_dev.m_dev[BT_SEQ]);
	ireg = sdio_readb(card->func, host_intstatus_reg, &ret);
	if (ret) {
		PRINTM(ERROR,
		       "BT: sdio_read_ioreg: CMD52 read int status register failed %d\n",
		       ret);
		goto done;
	}
	if (ireg != 0) {
		/*
		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
		 * Clear the interrupt status register and re-enable
		 * the interrupt
		 */
		PRINTM(INTR, "BT: INT %s: sdio_ireg = 0x%x\n", m_dev->name,
		       ireg);
		priv->adapter->irq_recv = ireg;
		sdio_writeb(card->func,
			    ~(ireg) & (DN_LD_HOST_INT_STATUS |
				       UP_LD_HOST_INT_STATUS),
			    host_intstatus_reg, &ret);
		if (ret) {
			PRINTM(ERROR,
			       "BT: sdio_write_ioreg: clear int status register failed\n");
			goto done;
		}
	} else {
		PRINTM(ERROR, "BT: ERR: ireg=0\n");
	}
	OS_INT_DISABLE;
	priv->adapter->sd_ireg |= ireg;
	OS_INT_RESTORE;
	bt_interrupt(m_dev);
done:
	LEAVE();
}
/** 
 *  @brief This function handles the interrupt.
 *  
 *  @param func  A pointer to sdio_func structure
 *  @return      n/a
 */
static void
sd_interrupt(struct sdio_func *func)
{
    bt_private *priv;
    struct hci_dev *hcidev;
    struct sdio_mmc_card *card;
    int ret = BT_STATUS_SUCCESS;
    u8 ireg = 0;

    ENTER();

    card = sdio_get_drvdata(func);
    if (!card || !card->priv) {
        PRINTM(INFO, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n",
               __FUNCTION__, func, card);
        LEAVE();
        return;
    }
    priv = card->priv;
    hcidev = priv->bt_dev.hcidev;

    ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
    if (ret) {
        PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n");
        goto done;
    }
    if (ireg != 0) {
        /* 
         * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
         * Clear the interrupt status register and re-enable the interrupt
         */
        PRINTM(INTR, "INT dev%d: sdio_ireg = 0x%x\n", hcidev->id, ireg);
        priv->adapter->irq_recv = ireg;
        sdio_writeb(card->func,
                    ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS),
                    HOST_INTSTATUS_REG, &ret);
        if (ret) {
            PRINTM(WARN,
                   "sdio_write_ioreg: clear int status register failed\n");
            goto done;
        }
    }
    OS_INT_DISABLE;
    priv->adapter->sd_ireg |= ireg;
    OS_INT_RESTORE;
    bt_interrupt(hcidev);
  done:
    LEAVE();
}