1. 中断定义:
#define GPIO_WIFI_IRQ 72
static struct wifi_platform_data wlan_device_control = {
.set_power = wlan_device_power,
........
};
static struct resource wlan_resources[] = {
[0] = {
.start = SS_SDIO1_PHYS,
.end = SS_SDIO1_PHYS + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.name = "bcmdhd_wlan_irq",
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
},
};
static struct platform_device sprd_wlan_device = {
.name = "bcmdhd_wlan",
.id = 1,
.dev = {
.platform_data = &wlan_device_control,
},
.resource = wlan_resources,
.num_resources = ARRAY_SIZE(wlan_resources),
};
static int __init wlan_device_init(void)
{
int ret;
gpio_request(GPIO_WIFI_IRQ, "oob_irq");
gpio_direction_input(GPIO_WIFI_IRQ);
wlan_resources[1].start = gpio_to_irq(GPIO_WIFI_IRQ);
wlan_resources[1].end = gpio_to_irq(GPIO_WIFI_IRQ);
gpio_request(GPIO_WIFI_SHUTDOWN,"wifi_pwd");
gpio_direction_output(GPIO_WIFI_SHUTDOWN, 0);
ret = platform_device_register(&ss_wlan_device);
return ret;
}
1.2 中断注册
int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handler,
void* oob_irq_handler_context)
{
int err = 0;
bcmsdh_osinfo->oob_irq_handler = oob_irq_handler;
bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context;
err = request_irq(bcmsdh_osinfo->oob_irq_num, wlan_oob_irq,
bcmsdh_osinfo->oob_irq_flags, "bcmsdh_sdmmc", bcmsdh);
return err;
}
中断处理函数即为:
static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
{
bcmsdh_oob_intr_set(bcmsdh, FALSE);
bcmsdh_osinfo->oob_irq_handler(bcmsdh_osinfo->oob_irq_handler_context);
return IRQ_HANDLED;
}
==================================================================================================
2. 另一种高级的
static void sdhci_host_wakeup_set( struct sdhci_host *host )
{
unsigned int val;
int ret;
if( (host->mmc->card )&& mmc_card_sdio(host->mmc->card) ){
sdhci_set_data1_to_gpio(host);
gpio_request(HOST_WAKEUP_GPIO, "host_wakeup_irq");
sdio_wakeup_irq = gpio_to_irq(HOST_WAKEUP_GPIO);
gpio_direction_input(HOST_WAKEUP_GPIO);
ret = request_threaded_irq(sdio_wakeup_irq, sdhci_wakeup_irq_handler, NULL,
IRQF_TRIGGER_LOW | IRQF_ONESHOT, "host_wakeup_irq", host);
if(ret){
printk(KERN_ERR "%s, request threaded irq error:%d\n",
mmc_hostname(host->mmc), ret);
return;
}
enable_irq_wake(sdio_wakeup_irq);
}
return;
}
static void sdhci_host_wakeup_clear(struct sdhci_host *host)
{
if( (host->mmc->card )&& mmc_card_sdio(host->mmc->card) ){
disable_irq_wake(sdio_wakeup_irq);
free_irq(sdio_wakeup_irq, host);
gpio_free(HOST_WAKEUP_GPIO);
sdhci_set_gpio_to_data1(host);
}
return;
}
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span><p>static irqreturn_t sdhci_wakeup_irq_handler(int irq, void *dev)
{
printk("sdhci_wakeup_irq_handler\n");
/* Disable interrupt before calling handler */
disable_irq_nosync(irq);</p><p> return IRQ_HANDLED;
}</p>
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span><p>void sdhci_set_data1_to_gpio(struct sdhci_host *host)
{
unsigned int val;
/* configurate sdio1 data1 to gpio when system in deep sleep */
val = BITS_PIN_DS(1) | BITS_PIN_AF(3) |
BIT_PIN_WPU | BIT_PIN_SLP_WPU |
BIT_PIN_SLP_IE ;
__raw_writel( val, CTL_PIN_BASE + REG_PIN_SD2_D1 );</p><p> printk("%s, PIN_SD2_D1_REG:0x%x\n", __func__, __raw_readl(REG_PIN_SD2_D1));
printk("sdhci_set_data1_to_gpio done\n");
}</p>
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
<p>void sdhci_set_gpio_to_data1(struct sdhci_host *host)
{
unsigned int val;
/* configurate sdio1 gpio to data1 when system wakeup */
val = __raw_readl( CTL_PIN_BASE + REG_PIN_SD2_D1 );
val = BITS_PIN_DS(1) | BITS_PIN_AF(0) |
BIT_PIN_WPU | BIT_PIN_SLP_NUL |
BIT_PIN_SLP_Z ;
__raw_writel( val, CTL_PIN_BASE + REG_PIN_SD2_D1 );</p><p> printk("%s, REG_PIN_SD2_D1:0x%x\n", __func__, __raw_readl(REG_PIN_SD2_D1));
printk("sdhci_set_gpio_to_data1 done\n");
}</p>