diff mbox

[v3,2/8] wlcore: set irq_flags in the board files instead of hiding behind a quirk

Message ID 1372860209-3504-3-git-send-email-coelho@ti.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Luciano Coelho July 3, 2013, 2:03 p.m. UTC
The platform_quirk element in the platform data was used to change the
way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
the irqflags used and treat edge trigger differently from the rest.

Instead of hiding this irq flag setting behind the quirk, have the
board files set the flags during initialization.  This will be more
meaningful than driver-specific quirks when we switch to DT.

Additionally, fix missing gpio_request() calls in the boarding files
(so that setting the flags actually works).

Cc: Tony Lindgren <tony@atomide.com>
Cc: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 arch/arm/mach-davinci/board-da850-evm.c      |    8 +++++-
 arch/arm/mach-omap2/board-4430sdp.c          |   18 +++++++++++++
 arch/arm/mach-omap2/board-omap3evm.c         |   19 ++++++++++++++
 arch/arm/mach-omap2/board-omap4panda.c       |   36 +++++++++++++++++++++-----
 arch/arm/mach-omap2/board-zoom-peripherals.c |   30 ++++++++++++++++++---
 drivers/net/wireless/ti/wlcore/debugfs.c     |    2 +-
 drivers/net/wireless/ti/wlcore/main.c        |   24 ++++++++++-------
 drivers/net/wireless/ti/wlcore/wlcore.h      |    5 ++--
 include/linux/wl12xx.h                       |    4 ---
 9 files changed, 118 insertions(+), 28 deletions(-)

Comments

Felipe Balbi July 3, 2013, 2:13 p.m. UTC | #1
Hi,

On Wed, Jul 03, 2013 at 05:03:23PM +0300, Luciano Coelho wrote:
> diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> index 56a9a4f..953f620 100644
> --- a/arch/arm/mach-omap2/board-4430sdp.c
> +++ b/arch/arm/mach-omap2/board-4430sdp.c
> @@ -703,12 +703,30 @@ static void __init omap4_sdp4430_wifi_init(void)
>  
>  	omap4_sdp4430_wifi_mux_init();
>  	omap4_sdp4430_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
> +
> +	ret = gpio_request_one(GPIO_WIFI_IRQ, GPIOF_IN, "GPIO_WIFI_IRQ");
> +	if (ret) {
> +		pr_err("error requesting wl12xx gpio: %d\n", ret);
> +		goto out;
> +	}
> +
> +	ret = irq_set_irq_type(gpio_to_irq(GPIO_WIFI_IRQ), IRQ_TYPE_LEVEL_HIGH);
> +	if (ret) {
> +		pr_err("error setting wl12xx irq type: %d\n", ret);
> +		goto free;
> +	}
> +
>  	ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
>  	if (ret)
>  		pr_err("Error setting wl12xx data: %d\n", ret);
> +
>  	ret = platform_device_register(&omap_vwlan_device);
>  	if (ret)
>  		pr_err("Error registering wl12xx device: %d\n", ret);
> +out:
> +	return;
> +free:
> +	gpio_free(GPIO_WIFI_IRQ);

actually, you should leave this GPIO requested in order to use it as
IRQ.

ditto for all others
Luciano Coelho July 3, 2013, 2:15 p.m. UTC | #2
On Wed, 2013-07-03 at 17:03 +0300, Luciano Coelho wrote:
> The platform_quirk element in the platform data was used to change the
> way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
> the irqflags used and treat edge trigger differently from the rest.
> 
> Instead of hiding this irq flag setting behind the quirk, have the
> board files set the flags during initialization.  This will be more
> meaningful than driver-specific quirks when we switch to DT.
> 
> Additionally, fix missing gpio_request() calls in the boarding files
> (so that setting the flags actually works).
> 
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Sekhar Nori <nsekhar@ti.com>
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---

[...]

> @@ -5928,16 +5927,21 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
>  	wlcore_adjust_conf(wl);
>  
>  	wl->irq = platform_get_irq(pdev, 0);
> -	wl->platform_quirks = pdata->platform_quirks;
>  	wl->if_ops = pdev_data->if_ops;
>  
> -	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
> -		irqflags = IRQF_TRIGGER_RISING;
> -	else
> -		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
> +	irq_data = irq_get_irq_data(wl->irq);
> +	if (!irq_data) {
> +		wl1271_error("couldn't get irq data for irq %d\n", wl->irq);
> +		ret = -EINVAL;
> +		goto out_free_nvs;
> +	}
> +
> +	wl->irq_flags = irqd_get_trigger_type(irq_data);

BTW, there seems to be a patch on its way to make reading the flags
easier (ie. no need to get the irq_data first):

http://mid.gmane.org/1367945288-5625-1-git-send-email-javier@dowhile0.org

I'm not sure if this is going to be taken in, but if it does, it would
be nice to change the code here to use the new irq_get_trigger_type()
function.

--
Luca.

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luciano Coelho July 3, 2013, 2:18 p.m. UTC | #3
On Wed, 2013-07-03 at 17:13 +0300, Felipe Balbi wrote:
> Hi,
> 
> On Wed, Jul 03, 2013 at 05:03:23PM +0300, Luciano Coelho wrote:
> > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > index 56a9a4f..953f620 100644
> > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > @@ -703,12 +703,30 @@ static void __init omap4_sdp4430_wifi_init(void)
> >  
> >  	omap4_sdp4430_wifi_mux_init();
> >  	omap4_sdp4430_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
> > +
> > +	ret = gpio_request_one(GPIO_WIFI_IRQ, GPIOF_IN, "GPIO_WIFI_IRQ");
> > +	if (ret) {
> > +		pr_err("error requesting wl12xx gpio: %d\n", ret);
> > +		goto out;
> > +	}
> > +
> > +	ret = irq_set_irq_type(gpio_to_irq(GPIO_WIFI_IRQ), IRQ_TYPE_LEVEL_HIGH);
> > +	if (ret) {
> > +		pr_err("error setting wl12xx irq type: %d\n", ret);
> > +		goto free;
> > +	}
> > +
> >  	ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
> >  	if (ret)
> >  		pr_err("Error setting wl12xx data: %d\n", ret);
> > +
> >  	ret = platform_device_register(&omap_vwlan_device);
> >  	if (ret)
> >  		pr_err("Error registering wl12xx device: %d\n", ret);
> > +out:
> > +	return;
> > +free:
> > +	gpio_free(GPIO_WIFI_IRQ);
> 
> actually, you should leave this GPIO requested in order to use it as
> IRQ.
> 
> ditto for all others

Actually, I don't need to use the GPIO if something goes wrong (ie.
setting the IRQ type or setting the platform data).  Notice that in the
normal cases (ie. without errors), I return before the gpio_free() is
called.

This is not really needed, but it's a bit cleaner and we can probably
release some resources.

--
Luca.

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Felipe Balbi July 3, 2013, 2:23 p.m. UTC | #4
On Wed, Jul 03, 2013 at 05:18:14PM +0300, Luciano Coelho wrote:
> On Wed, 2013-07-03 at 17:13 +0300, Felipe Balbi wrote:
> > Hi,
> > 
> > On Wed, Jul 03, 2013 at 05:03:23PM +0300, Luciano Coelho wrote:
> > > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > > index 56a9a4f..953f620 100644
> > > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > > @@ -703,12 +703,30 @@ static void __init omap4_sdp4430_wifi_init(void)
> > >  
> > >  	omap4_sdp4430_wifi_mux_init();
> > >  	omap4_sdp4430_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
> > > +
> > > +	ret = gpio_request_one(GPIO_WIFI_IRQ, GPIOF_IN, "GPIO_WIFI_IRQ");
> > > +	if (ret) {
> > > +		pr_err("error requesting wl12xx gpio: %d\n", ret);
> > > +		goto out;
> > > +	}
> > > +
> > > +	ret = irq_set_irq_type(gpio_to_irq(GPIO_WIFI_IRQ), IRQ_TYPE_LEVEL_HIGH);
> > > +	if (ret) {
> > > +		pr_err("error setting wl12xx irq type: %d\n", ret);
> > > +		goto free;
> > > +	}
> > > +
> > >  	ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
> > >  	if (ret)
> > >  		pr_err("Error setting wl12xx data: %d\n", ret);
> > > +
> > >  	ret = platform_device_register(&omap_vwlan_device);
> > >  	if (ret)
> > >  		pr_err("Error registering wl12xx device: %d\n", ret);
> > > +out:
> > > +	return;
> > > +free:
> > > +	gpio_free(GPIO_WIFI_IRQ);
> > 
> > actually, you should leave this GPIO requested in order to use it as
> > IRQ.
> > 
> > ditto for all others
> 
> Actually, I don't need to use the GPIO if something goes wrong (ie.
> setting the IRQ type or setting the platform data).  Notice that in the
> normal cases (ie. without errors), I return before the gpio_free() is
> called.

hah, missed the 'return' call, my bad :-p

Reviewed-by: Felipe Balbi <balbi@ti.com>
Corrected-my-broken-eye-sight-by: Luciano Coelho <coelho@ti.com>
Javier Martinez Canillas July 3, 2013, 3:12 p.m. UTC | #5
On Wed, Jul 3, 2013 at 4:15 PM, Luciano Coelho <coelho@ti.com> wrote:
> On Wed, 2013-07-03 at 17:03 +0300, Luciano Coelho wrote:
>> The platform_quirk element in the platform data was used to change the
>> way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
>> the irqflags used and treat edge trigger differently from the rest.
>>
>> Instead of hiding this irq flag setting behind the quirk, have the
>> board files set the flags during initialization.  This will be more
>> meaningful than driver-specific quirks when we switch to DT.
>>
>> Additionally, fix missing gpio_request() calls in the boarding files
>> (so that setting the flags actually works).
>>
>> Cc: Tony Lindgren <tony@atomide.com>
>> Cc: Sekhar Nori <nsekhar@ti.com>
>> Signed-off-by: Luciano Coelho <coelho@ti.com>
>> ---
>
> [...]
>
>> @@ -5928,16 +5927,21 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
>>       wlcore_adjust_conf(wl);
>>
>>       wl->irq = platform_get_irq(pdev, 0);
>> -     wl->platform_quirks = pdata->platform_quirks;
>>       wl->if_ops = pdev_data->if_ops;
>>
>> -     if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
>> -             irqflags = IRQF_TRIGGER_RISING;
>> -     else
>> -             irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
>> +     irq_data = irq_get_irq_data(wl->irq);
>> +     if (!irq_data) {
>> +             wl1271_error("couldn't get irq data for irq %d\n", wl->irq);
>> +             ret = -EINVAL;
>> +             goto out_free_nvs;
>> +     }
>> +
>> +     wl->irq_flags = irqd_get_trigger_type(irq_data);
>
> BTW, there seems to be a patch on its way to make reading the flags
> easier (ie. no need to get the irq_data first):
>
> http://mid.gmane.org/1367945288-5625-1-git-send-email-javier@dowhile0.org
>
> I'm not sure if this is going to be taken in, but if it does, it would
> be nice to change the code here to use the new irq_get_trigger_type()
> function.
>
> --
> Luca.
>

Hi Luca

That patch has been already merged in Linus tree as commit 1f6236bf
("genirq: Add irq_get_trigger_type() to get IRQ flags").

So yes, it would be better if you can use irq_get_trigger_type()
instead calling irq_get_irq_data() + irqd_get_trigger_type().

Best regards,
Javier
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sekhar Nori July 4, 2013, 4:46 a.m. UTC | #6
On 7/3/2013 7:33 PM, Luciano Coelho wrote:
> The platform_quirk element in the platform data was used to change the
> way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
> the irqflags used and treat edge trigger differently from the rest.
> 
> Instead of hiding this irq flag setting behind the quirk, have the
> board files set the flags during initialization.  This will be more
> meaningful than driver-specific quirks when we switch to DT.
> 
> Additionally, fix missing gpio_request() calls in the boarding files
> (so that setting the flags actually works).
> 
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Sekhar Nori <nsekhar@ti.com>
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---
>  arch/arm/mach-davinci/board-da850-evm.c      |    8 +++++-

For the board-da850-evm.c change,

Acked-by: Sekhar Nori <nsekhar@ti.com>

Thanks,
Sekhar
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luciano Coelho July 4, 2013, 2:21 p.m. UTC | #7
On Wed, 2013-07-03 at 17:12 +0200, Javier Martinez Canillas wrote:
> On Wed, Jul 3, 2013 at 4:15 PM, Luciano Coelho <coelho@ti.com> wrote:
> > On Wed, 2013-07-03 at 17:03 +0300, Luciano Coelho wrote:
> >> The platform_quirk element in the platform data was used to change the
> >> way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
> >> the irqflags used and treat edge trigger differently from the rest.
> >>
> >> Instead of hiding this irq flag setting behind the quirk, have the
> >> board files set the flags during initialization.  This will be more
> >> meaningful than driver-specific quirks when we switch to DT.
> >>
> >> Additionally, fix missing gpio_request() calls in the boarding files
> >> (so that setting the flags actually works).
> >>
> >> Cc: Tony Lindgren <tony@atomide.com>
> >> Cc: Sekhar Nori <nsekhar@ti.com>
> >> Signed-off-by: Luciano Coelho <coelho@ti.com>
> >> ---
> >
> > [...]
> >
> >> @@ -5928,16 +5927,21 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
> >>       wlcore_adjust_conf(wl);
> >>
> >>       wl->irq = platform_get_irq(pdev, 0);
> >> -     wl->platform_quirks = pdata->platform_quirks;
> >>       wl->if_ops = pdev_data->if_ops;
> >>
> >> -     if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
> >> -             irqflags = IRQF_TRIGGER_RISING;
> >> -     else
> >> -             irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
> >> +     irq_data = irq_get_irq_data(wl->irq);
> >> +     if (!irq_data) {
> >> +             wl1271_error("couldn't get irq data for irq %d\n", wl->irq);
> >> +             ret = -EINVAL;
> >> +             goto out_free_nvs;
> >> +     }
> >> +
> >> +     wl->irq_flags = irqd_get_trigger_type(irq_data);
> >
> > BTW, there seems to be a patch on its way to make reading the flags
> > easier (ie. no need to get the irq_data first):
> >
> > http://mid.gmane.org/1367945288-5625-1-git-send-email-javier@dowhile0.org
> >
> > I'm not sure if this is going to be taken in, but if it does, it would
> > be nice to change the code here to use the new irq_get_trigger_type()
> > function.

> That patch has been already merged in Linus tree as commit 1f6236bf
> ("genirq: Add irq_get_trigger_type() to get IRQ flags").
> 
> So yes, it would be better if you can use irq_get_trigger_type()
> instead calling irq_get_irq_data() + irqd_get_trigger_type().

That's great, thanks! I'll make this change as soon as I get your patch
into my tree (ie. after the merge window closes).

--
Luca.

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 8a24b6c..544b6fa 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1378,7 +1378,6 @@  static const short da850_wl12xx_pins[] __initconst = {
 static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
 	.irq			= -1,
 	.board_ref_clock	= WL12XX_REFCLOCK_38,
-	.platform_quirks	= WL12XX_PLATFORM_QUIRK_EDGE_IRQ,
 };
 
 static __init int da850_wl12xx_init(void)
@@ -1409,6 +1408,13 @@  static __init int da850_wl12xx_init(void)
 		goto free_wlan_en;
 	}
 
+	ret = irq_set_irq_type(gpio_to_irq(DA850_WLAN_IRQ),
+			       IRQ_TYPE_EDGE_RISING);
+	if (ret) {
+		pr_err("Could not set wl12xx irq type: %d\n", ret);
+		goto free;
+	}
+
 	da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
 
 	ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 56a9a4f..953f620 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -703,12 +703,30 @@  static void __init omap4_sdp4430_wifi_init(void)
 
 	omap4_sdp4430_wifi_mux_init();
 	omap4_sdp4430_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
+
+	ret = gpio_request_one(GPIO_WIFI_IRQ, GPIOF_IN, "GPIO_WIFI_IRQ");
+	if (ret) {
+		pr_err("error requesting wl12xx gpio: %d\n", ret);
+		goto out;
+	}
+
+	ret = irq_set_irq_type(gpio_to_irq(GPIO_WIFI_IRQ), IRQ_TYPE_LEVEL_HIGH);
+	if (ret) {
+		pr_err("error setting wl12xx irq type: %d\n", ret);
+		goto free;
+	}
+
 	ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
 	if (ret)
 		pr_err("Error setting wl12xx data: %d\n", ret);
+
 	ret = platform_device_register(&omap_vwlan_device);
 	if (ret)
 		pr_err("Error registering wl12xx device: %d\n", ret);
+out:
+	return;
+free:
+	gpio_free(GPIO_WIFI_IRQ);
 }
 
 static void __init omap_4430sdp_init(void)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index f76d0de..8abce3cd 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -612,12 +612,31 @@  static void __init omap3_evm_wl12xx_init(void)
 
 	/* WL12xx WLAN Init */
 	omap3evm_wlan_data.irq = gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO);
+
+	ret = gpio_request_one(OMAP3EVM_WLAN_IRQ_GPIO, GPIOF_IN,
+			       "OMAP3EVM_WLAN_IRQ_GPIO");
+	if (ret) {
+		pr_err("error requesting wl12xx gpio: %d\n", ret);
+		goto out;
+	}
+
+	ret = irq_set_irq_type(gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO),
+			       IRQ_TYPE_LEVEL_HIGH);
+	if (ret) {
+		pr_err("error setting wl12xx irq type: %d\n", ret);
+		goto free;
+	}
+
 	ret = wl12xx_set_platform_data(&omap3evm_wlan_data);
 	if (ret)
 		pr_err("error setting wl12xx data: %d\n", ret);
 	ret = platform_device_register(&omap3evm_wlan_regulator);
 	if (ret)
 		pr_err("error registering wl12xx device: %d\n", ret);
+out:
+	return;
+free:
+	gpio_free(OMAP3EVM_WLAN_IRQ_GPIO);
 #endif
 }
 
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 1e2c75e..5b33626 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -413,20 +413,44 @@  static void omap4_panda_init_rev(void)
 	}
 }
 
+static void __init omap4_panda_wilink_init(void)
+{
+	int ret;
+
+	omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
+
+	ret = gpio_request_one(GPIO_WIFI_IRQ, GPIOF_IN, "GPIO_WIFI_IRQ");
+	if (ret) {
+		pr_err("error requesting wl12xx gpio: %d\n", ret);
+		goto out;
+	}
+
+	ret = irq_set_irq_type(gpio_to_irq(GPIO_WIFI_IRQ), IRQ_TYPE_LEVEL_HIGH);
+	if (ret) {
+		pr_err("error setting wl12xx irq type: %d\n", ret);
+		goto free;
+	}
+
+	ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
+	if (ret) {
+		pr_err("error setting wl12xx data: %d\n", ret);
+		goto free;
+	}
+out:
+	return;
+free:
+	gpio_free(GPIO_WIFI_IRQ);
+}
+
 static void __init omap4_panda_init(void)
 {
 	int package = OMAP_PACKAGE_CBS;
-	int ret;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		package = OMAP_PACKAGE_CBL;
 	omap4_mux_init(board_mux, NULL, package);
 
-	omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
-	ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
-	if (ret)
-		pr_err("error setting wl12xx data: %d\n", ret);
-
+	omap4_panda_wilink_init();
 	omap4_panda_init_rev();
 	omap4_panda_i2c_init();
 	platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index a90375d..4f84cf9 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -339,16 +339,40 @@  static void enable_board_wakeup_source(void)
 		OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
-void __init zoom_peripherals_init(void)
+static void __init zoom_wilink_init(void)
 {
 	int ret;
 
 	omap_zoom_wlan_data.irq = gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO);
-	ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
 
-	if (ret)
+	ret = gpio_request_one(OMAP_ZOOM_WLAN_IRQ_GPIO, GPIOF_IN,
+			       "OMAP_ZOOM_WLAN_IRQ_GPIO");
+	if (ret) {
+		pr_err("error requesting wl12xx gpio: %d\n", ret);
+		goto out;
+	}
+
+	ret = irq_set_irq_type(gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO),
+			       IRQ_TYPE_LEVEL_HIGH);
+	if (ret) {
+		pr_err("error setting wl12xx irq type: %d\n", ret);
+		goto free;
+	}
+
+	ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
+	if (ret) {
 		pr_err("error setting wl12xx data: %d\n", ret);
+		goto free;
+	}
+out:
+	return;
+free:
+	gpio_free(OMAP_ZOOM_WLAN_IRQ_GPIO);
+}
 
+void __init zoom_peripherals_init(void)
+{
+	zoom_wilink_init();
 	omap_hsmmc_init(mmc);
 	omap_i2c_init();
 	pwm_add_table(zoom_pwm_lookup, ARRAY_SIZE(zoom_pwm_lookup));
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index c3e1f79..5eff663 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -486,7 +486,7 @@  static ssize_t driver_state_read(struct file *file, char __user *user_buf,
 	DRIVER_STATE_PRINT_HEX(irq);
 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
-	DRIVER_STATE_PRINT_HEX(platform_quirks);
+	DRIVER_STATE_PRINT_HEX(irq_flags);
 	DRIVER_STATE_PRINT_HEX(chip.id);
 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b8db55c..7b5d0cc 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -27,6 +27,7 @@ 
 #include <linux/vmalloc.h>
 #include <linux/wl12xx.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 
 #include "wlcore.h"
 #include "debug.h"
@@ -516,7 +517,7 @@  static int wlcore_irq_locked(struct wl1271 *wl)
 	 * In case edge triggered interrupt must be used, we cannot iterate
 	 * more than once without introducing race conditions with the hardirq.
 	 */
-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+	if (wl->irq_flags & IRQF_TRIGGER_RISING)
 		loopcount = 1;
 
 	wl1271_debug(DEBUG_IRQ, "IRQ work");
@@ -5765,7 +5766,6 @@  struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
 	wl->ap_ps_map = 0;
 	wl->ap_fw_ps_map = 0;
 	wl->quirks = 0;
-	wl->platform_quirks = 0;
 	wl->system_hlid = WL12XX_SYSTEM_HLID;
 	wl->active_sta_count = 0;
 	wl->active_link_count = 0;
@@ -5900,8 +5900,7 @@  static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	struct wl1271 *wl = context;
 	struct platform_device *pdev = wl->pdev;
 	struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
-	struct wl12xx_platform_data *pdata = pdev_data->pdata;
-	unsigned long irqflags;
+	struct irq_data *irq_data;
 	int ret;
 
 	if (fw) {
@@ -5928,16 +5927,21 @@  static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	wlcore_adjust_conf(wl);
 
 	wl->irq = platform_get_irq(pdev, 0);
-	wl->platform_quirks = pdata->platform_quirks;
 	wl->if_ops = pdev_data->if_ops;
 
-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
-		irqflags = IRQF_TRIGGER_RISING;
-	else
-		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+	irq_data = irq_get_irq_data(wl->irq);
+	if (!irq_data) {
+		wl1271_error("couldn't get irq data for irq %d\n", wl->irq);
+		ret = -EINVAL;
+		goto out_free_nvs;
+	}
+
+	wl->irq_flags = irqd_get_trigger_type(irq_data);
+	/* Since we don't use the primary handler, we must set ONESHOT */
+	wl->irq_flags |= IRQF_ONESHOT;
 
 	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
-				   irqflags, pdev->name, wl);
+				   wl->irq_flags, pdev->name, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
 		goto out_free_nvs;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0034979..8306bde 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -185,6 +185,8 @@  struct wl1271 {
 
 	int irq;
 
+	int irq_flags;
+
 	spinlock_t wl_lock;
 
 	enum wlcore_state state;
@@ -384,9 +386,6 @@  struct wl1271 {
 	/* Quirks of specific hardware revisions */
 	unsigned int quirks;
 
-	/* Platform limitations */
-	unsigned int platform_quirks;
-
 	/* number of currently active RX BA sessions */
 	int ba_rx_session_count;
 
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index b516b4f..1bfcd19 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -59,13 +59,9 @@  struct wl12xx_platform_data {
 	int irq;
 	int board_ref_clock;
 	int board_tcxo_clock;
-	unsigned long platform_quirks;
 	bool pwr_in_suspend;
 };
 
-/* Platform does not support level trigger interrupts */
-#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ	BIT(0)
-
 #ifdef CONFIG_WILINK_PLATFORM_DATA
 
 int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);