linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] irq: Consider a negative return value of irq_startup() as an error
@ 2014-02-25 16:28 Jean-Jacques Hiblot
  2014-02-26 22:15 ` Thomas Gleixner
  0 siblings, 1 reply; 17+ messages in thread
From: Jean-Jacques Hiblot @ 2014-02-25 16:28 UTC (permalink / raw)
  To: tglx, linus.walleij
  Cc: grant.likely, linux-kernel, linux-arm-kernel, Jean-Jacques Hiblot

The irq_startup() function returns the return value of the irq_startup callback
of the underlying irq_chip. Currently this value only tells if the interrupt is
pending, but we can make it also return an error code when it fails.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
---

Hi Thomas,

This patch updates the semantic of the return value of the irq_startup()
callback of an irq_chip : a negative value indicates an error. The purpose is
to make __setup_irq() fail if the irq_chip can't startup the interrupt.
I checked in the kernel for drivers impacted by this. It turns out that most
of the implementation of irq_startup() return 0. The only drivers that return
non-zero values are:
 * arch/x86/kernel/apic/io_apic.c: returns 1 when an interrupt is pending
 * drivers/pinctrl/pinctrl-adi2.c: may return -ENODEV.

GPIO-based irq_chip could use this feature because an output gpio can't be used
as an interrupt, and thus a call to irq_startup() is likely to fail. You can
check out http://www.spinics.net/lists/arm-kernel/msg302713.html for a
reference.

Regards,

Jean-Jacques

 include/linux/irq.h    | 2 ++
 kernel/irq/autoprobe.c | 2 +-
 kernel/irq/manage.c    | 4 +++-
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 7dc1003..d566855 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -282,6 +282,8 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
  *
  * @name:		name for /proc/interrupts
  * @irq_startup:	start up the interrupt (defaults to ->enable if NULL)
+ *			negative return values indicate an error, otherwise the
+ *			return values indicates if an interrupt is pending
  * @irq_shutdown:	shut down the interrupt (defaults to ->disable if NULL)
  * @irq_enable:		enable the interrupt (defaults to chip->unmask if NULL)
  * @irq_disable:	disable the interrupt
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 0119b9d..64794fa 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -70,7 +70,7 @@ unsigned long probe_irq_on(void)
 		raw_spin_lock_irq(&desc->lock);
 		if (!desc->action && irq_settings_can_probe(desc)) {
 			desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
-			if (irq_startup(desc, false))
+			if (irq_startup(desc, false) > 0)
 				desc->istate |= IRQS_PENDING;
 		}
 		raw_spin_unlock_irq(&desc->lock);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 481a13c..58c6be0 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1116,7 +1116,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 			desc->istate |= IRQS_ONESHOT;
 
 		if (irq_settings_can_autoenable(desc))
-			irq_startup(desc, true);
+			ret = irq_startup(desc, true);
+			if (ret < 0)
+				goto out_mask;
 		else
 			/* Undo nested disables: */
 			desc->depth = 1;
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Consider a negative return value of irq_startup() as an error
  2014-02-25 16:28 [PATCH] irq: Consider a negative return value of irq_startup() as an error Jean-Jacques Hiblot
@ 2014-02-26 22:15 ` Thomas Gleixner
  2014-02-27 16:03   ` Jean-Jacques Hiblot
  2014-03-07  2:49   ` [PATCH] irq: Consider a negative return value of irq_startup() as an error Linus Walleij
  0 siblings, 2 replies; 17+ messages in thread
From: Thomas Gleixner @ 2014-02-26 22:15 UTC (permalink / raw)
  To: Jean-Jacques Hiblot
  Cc: linus.walleij, grant.likely, linux-kernel, linux-arm-kernel

On Tue, 25 Feb 2014, Jean-Jacques Hiblot wrote:

> The irq_startup() function returns the return value of the
> irq_startup callback of the underlying irq_chip. Currently this
> value only tells if the interrupt is pending, but we can make it
> also return an error code when it fails.
> 
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> 
> Hi Thomas,
> 
> This patch updates the semantic of the return value of the irq_startup()
> callback of an irq_chip : a negative value indicates an error. The purpose is
> to make __setup_irq() fail if the irq_chip can't startup the interrupt.

How does that work?

    unsigned int    (*irq_startup)(struct irq_data *data);

> I checked in the kernel for drivers impacted by this. It turns out that most
> of the implementation of irq_startup() return 0. The only drivers that return
> non-zero values are:
>  * arch/x86/kernel/apic/io_apic.c: returns 1 when an interrupt is pending
>  * drivers/pinctrl/pinctrl-adi2.c: may return -ENODEV.

   which is wrong to begin with.
 
> GPIO-based irq_chip could use this feature because an output gpio
> can't be used as an interrupt, and thus a call to irq_startup() is
> likely to fail. You can check out
> http://www.spinics.net/lists/arm-kernel/msg302713.html for a
> reference.

And that tells me that the design of the gpio stuff is just wrong.

The whole drviers/gpio directory is full of this gpio_lock_as_irq()
called from the guts of irq_chip callbacks braindamage.

The comment above gpiod_lock_as_irq() is so wrong it's not even funny
anymore.

"....or in the .irq_enable() from its irq_chip implementation ..."

	void            (*irq_enable)(struct irq_data *data);

So how does that help, if the gpio is not available as irq?

And no, you are not going to cure that design brainfart by adding a
negative return value to a function returning unsigned int. And I'm
not going to accept anything which is just a duct tape based
workaround for a complete braindamaged design.

Lets look at the usage sites:

The following irqchip callback implementations printk some blurb and
proceed:

 sirfsoc_gpio_irq_startup
 nmk_gpio_irq_startup
 msm_gpio_irq_startup
 u300_gpio_irq_enable
 byt_irq_startup
 mcp23s08_irq_startup
 lp_irq_startup
 intel_mid_irq_startup
 em_gio_irq_startup
 bcm_kona_gpio_irq_startup
 adnp_irq_startup

The following functions return an error code from the set_type
callback:

 tegra_gpio_irq_set_type
 gpio_irq_type

The whole idiocy starts with commit d468bf9e, which tells people to
call this from irq_startup/enable. But it fails to tell, that this is
pointless because it wont prevent the interrupt from starting up.

So 11 SoC lemmings followed and added this completely pointless
nonsense to their drivers.

Two lemmings added it to a function which can actually fail. Failure
as well, because there is no guarantee that this function gets invoked
before request_irq(). What's worse is that if request_irq() succeeds
then the following code which tries to set the type fails for no
obvious reason.

Now at least Jean-Jacques tried to make it actually fail, but that
turns out to be a failure on its own.

Dammit, I told you folks often enough that workarounds in some
subsystem do not actually cure a shortcoming in the core code. When
the core code was written, the GPIO case which might actually fail was
definitly not thought of. But that's not a reason for adding
tasteless and useless workarounds to the GPIO subsystem.

Of course you encouraged people to copy that nonsense all over the
place. All startup functions do the same thing:

    if (gpio_lock_as_irq() < 0)
       dev_err("BLA");
    unmask_irq();

Plus the shutdown functions having the gpio_unlock_as_irq() +
mask_irq() sequence. Sigh.

So the proper solution to the problem if we want to use irq_startup()
is:

  Change the return value of the irq_startup() callback to int and
  fixup all existing implementations. This wants to be done with a
  coccinelle script. If you hurry up, I might squeeze it into 3.14 as
  there is no risk at all. Otherwise this is going to happen after the
  3.15 merge window closes.

  After that's done, remove all the copies of startup/shutdown
  nonsense in drivers/gpio and force all gpio chips to call
  gpio_set_irq_chip*() instead of irq_set_irq_chip*() and add generic
  irq_startup/shutdown callbacks which are implemented in the gpiolib
  core code.

There is a less intrusive alternative solution:

  Mark the interrupt as GPIO based in the core and let the core call
  conditonally the gpio_[un]lock_as_irq functions.

And no, I'm not going to provide you the proper solution on the silver
tablet this time. Go and figure it out yourself and if you're
confident enough that it might be an acceptable solution, post it and
we'll see.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Consider a negative return value of irq_startup() as an error
  2014-02-26 22:15 ` Thomas Gleixner
@ 2014-02-27 16:03   ` Jean-Jacques Hiblot
  2014-02-27 17:21     ` [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int Jean-Jacques Hiblot
  2014-03-07  2:49   ` [PATCH] irq: Consider a negative return value of irq_startup() as an error Linus Walleij
  1 sibling, 1 reply; 17+ messages in thread
From: Jean-Jacques Hiblot @ 2014-02-27 16:03 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Jean-Jacques Hiblot, Linus Walleij, Grant Likely,
	Linux Kernel Mailing List, linux-arm-kernel

2014-02-26 23:15 GMT+01:00 Thomas Gleixner <tglx@linutronix.de>:
> On Tue, 25 Feb 2014, Jean-Jacques Hiblot wrote:
>
>> The irq_startup() function returns the return value of the
>> irq_startup callback of the underlying irq_chip. Currently this
>> value only tells if the interrupt is pending, but we can make it
>> also return an error code when it fails.
>>
>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
>> ---
>>
>> Hi Thomas,
>>
>> This patch updates the semantic of the return value of the irq_startup()
>> callback of an irq_chip : a negative value indicates an error. The purpose is
>> to make __setup_irq() fail if the irq_chip can't startup the interrupt.
>
> How does that work?
>
>     unsigned int    (*irq_startup)(struct irq_data *data);
well .. no excuse sir
>
>> I checked in the kernel for drivers impacted by this. It turns out that most
>> of the implementation of irq_startup() return 0. The only drivers that return
>> non-zero values are:
>>  * arch/x86/kernel/apic/io_apic.c: returns 1 when an interrupt is pending
>>  * drivers/pinctrl/pinctrl-adi2.c: may return -ENODEV.
>
>    which is wrong to begin with.
>
>> GPIO-based irq_chip could use this feature because an output gpio
>> can't be used as an interrupt, and thus a call to irq_startup() is
>> likely to fail. You can check out
>> http://www.spinics.net/lists/arm-kernel/msg302713.html for a
>> reference.
>
> And that tells me that the design of the gpio stuff is just wrong.
>
> The whole drviers/gpio directory is full of this gpio_lock_as_irq()
> called from the guts of irq_chip callbacks braindamage.
>
> The comment above gpiod_lock_as_irq() is so wrong it's not even funny
> anymore.
>
> "....or in the .irq_enable() from its irq_chip implementation ..."
>
>         void            (*irq_enable)(struct irq_data *data);
>
> So how does that help, if the gpio is not available as irq?
>
> And no, you are not going to cure that design brainfart by adding a
> negative return value to a function returning unsigned int. And I'm
> not going to accept anything which is just a duct tape based
> workaround for a complete braindamaged design.
>
> Lets look at the usage sites:
>
> The following irqchip callback implementations printk some blurb and
> proceed:
>
>  sirfsoc_gpio_irq_startup
>  nmk_gpio_irq_startup
>  msm_gpio_irq_startup
>  u300_gpio_irq_enable
>  byt_irq_startup
>  mcp23s08_irq_startup
>  lp_irq_startup
>  intel_mid_irq_startup
>  em_gio_irq_startup
>  bcm_kona_gpio_irq_startup
>  adnp_irq_startup
>
> The following functions return an error code from the set_type
> callback:
>
>  tegra_gpio_irq_set_type
>  gpio_irq_type
>
> The whole idiocy starts with commit d468bf9e, which tells people to
> call this from irq_startup/enable. But it fails to tell, that this is
> pointless because it wont prevent the interrupt from starting up.
>
>From a GPIO subsystem standpoint, the IRQ lock is sensible because
using a gpio as an interrupt source, adds some restrictions to its
usage. Ouput configuration and IRQ configuration are exclusive for
example.
That  request_irq() succeeds if a GPIO can't be used as interrupt, is
however a problem. It can be fixed.


> So 11 SoC lemmings followed and added this completely pointless
> nonsense to their drivers.
>
> Two lemmings added it to a function which can actually fail. Failure
> as well, because there is no guarantee that this function gets invoked
> before request_irq(). What's worse is that if request_irq() succeeds
> then the following code which tries to set the type fails for no
> obvious reason.
>
> Now at least Jean-Jacques tried to make it actually fail, but that
> turns out to be a failure on its own.
just to clarify: is the failure the problem with the unsigned or the
principle of making request_irq fail ?

>
> Dammit, I told you folks often enough that workarounds in some
> subsystem do not actually cure a shortcoming in the core code. When
> the core code was written, the GPIO case which might actually fail was
> definitly not thought of. But that's not a reason for adding
> tasteless and useless workarounds to the GPIO subsystem.
>
> Of course you encouraged people to copy that nonsense all over the
> place. All startup functions do the same thing:
>
>     if (gpio_lock_as_irq() < 0)
>        dev_err("BLA");
>     unmask_irq();
>
> Plus the shutdown functions having the gpio_unlock_as_irq() +
> mask_irq() sequence. Sigh.
>
> So the proper solution to the problem if we want to use irq_startup()
> is:
>
>   Change the return value of the irq_startup() callback to int and
>   fixup all existing implementations. This wants to be done with a
>   coccinelle script. If you hurry up, I might squeeze it into 3.14 as
>   there is no risk at all. Otherwise this is going to happen after the
>   3.15 merge window closes.
I'll post a patch doing just this in the next email.

Jean-Jacques
>
>   After that's done, remove all the copies of startup/shutdown
>   nonsense in drivers/gpio and force all gpio chips to call
>   gpio_set_irq_chip*() instead of irq_set_irq_chip*() and add generic
>   irq_startup/shutdown callbacks which are implemented in the gpiolib
>   core code.
>
> There is a less intrusive alternative solution:
>
>   Mark the interrupt as GPIO based in the core and let the core call
>   conditonally the gpio_[un]lock_as_irq functions.
>
> And no, I'm not going to provide you the proper solution on the silver
> tablet this time. Go and figure it out yourself and if you're
> confident enough that it might be an acceptable solution, post it and
> we'll see.
>
> Thanks,
>
>         tglx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-02-27 16:03   ` Jean-Jacques Hiblot
@ 2014-02-27 17:21     ` Jean-Jacques Hiblot
  2014-02-28 22:52       ` James Hogan
  0 siblings, 1 reply; 17+ messages in thread
From: Jean-Jacques Hiblot @ 2014-02-27 17:21 UTC (permalink / raw)
  To: tglx
  Cc: linus.walleij, grant.likely, linux-kernel, linux-arm-kernel,
	Jean-Jacques Hiblot

This patch changes the return type of the irq_startup() callback in irq_chip
from unsigned int to int, and modify the IRQ drivers providing this feature.
This allows the callback to return negative error codes.
This patch prepares the way for another patch that'll make request_irq() fail
when irq_startup() fails.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
---
 arch/arm/mach-omap2/gpmc.c                | 2 +-
 arch/blackfin/mach-common/ints-priority.c | 2 +-
 arch/ia64/hp/sim/hpsim_irq.c              | 2 +-
 arch/ia64/kernel/iosapic.c                | 4 ++--
 arch/ia64/kernel/irq_lsapic.c             | 2 +-
 arch/ia64/sn/kernel/irq.c                 | 2 +-
 arch/m68k/apollo/dn_ints.c                | 2 +-
 arch/m68k/atari/ataints.c                 | 4 ++--
 arch/m68k/include/asm/irq.h               | 4 ++--
 arch/m68k/kernel/ints.c                   | 4 ++--
 arch/m68k/mac/macints.c                   | 4 ++--
 arch/m68k/platform/coldfire/intc-2.c      | 2 +-
 arch/m68k/platform/coldfire/intc-simr.c   | 2 +-
 arch/m68k/q40/q40ints.c                   | 2 +-
 arch/metag/kernel/irq.c                   | 2 +-
 arch/mips/jz4740/gpio.c                   | 2 +-
 arch/mips/kernel/irq_cpu.c                | 2 +-
 arch/mips/lantiq/irq.c                    | 2 +-
 arch/mips/sgi-ip27/ip27-irq-pci.c         | 2 +-
 arch/powerpc/platforms/powermac/pic.c     | 2 +-
 arch/powerpc/platforms/wsp/ics.c          | 4 ++--
 arch/powerpc/sysdev/mpic.c                | 2 +-
 arch/powerpc/sysdev/xics/ics-opal.c       | 2 +-
 arch/powerpc/sysdev/xics/ics-rtas.c       | 2 +-
 arch/sparc/kernel/leon_kernel.c           | 2 +-
 arch/sparc/kernel/leon_pci_grpci1.c       | 2 +-
 arch/sparc/kernel/leon_pci_grpci2.c       | 2 +-
 arch/sparc/kernel/pcic.c                  | 2 +-
 arch/sparc/kernel/sun4d_irq.c             | 2 +-
 arch/sparc/kernel/sun4m_irq.c             | 2 +-
 arch/tile/kernel/pci_gx.c                 | 2 +-
 arch/x86/kernel/apic/io_apic.c            | 2 +-
 arch/x86/platform/visws/visws_quirks.c    | 2 +-
 drivers/gpio/gpio-adnp.c                  | 2 +-
 drivers/gpio/gpio-bcm-kona.c              | 2 +-
 drivers/gpio/gpio-em.c                    | 2 +-
 drivers/gpio/gpio-intel-mid.c             | 2 +-
 drivers/gpio/gpio-lynxpoint.c             | 2 +-
 drivers/gpio/gpio-mcp23s08.c              | 2 +-
 drivers/gpio/gpio-tz1090.c                | 2 +-
 drivers/irqchip/irq-metag.c               | 4 ++--
 drivers/pinctrl/pinctrl-adi2.c            | 2 +-
 drivers/pinctrl/pinctrl-baytrail.c        | 2 +-
 drivers/pinctrl/pinctrl-msm.c             | 2 +-
 drivers/pinctrl/pinctrl-nomadik.c         | 2 +-
 drivers/pinctrl/sirf/pinctrl-sirf.c       | 2 +-
 drivers/xen/events/events_base.c          | 4 ++--
 include/linux/irq.h                       | 2 +-
 kernel/irq/dummychip.c                    | 2 +-
 49 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index ab43755..1c905e4 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -714,7 +714,7 @@ static void gpmc_irq_enable(struct irq_data *p)
 
 static void gpmc_irq_noop(struct irq_data *data) { }
 
-static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
+static int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
 
 static int gpmc_setup_irq(void)
 {
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 867b7ce..9a25b64 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -734,7 +734,7 @@ static void bfin_gpio_unmask_irq(struct irq_data *d)
 	set_gpio_maska(irq_to_gpio(d->irq), 1);
 }
 
-static unsigned int bfin_gpio_irq_startup(struct irq_data *d)
+static int bfin_gpio_irq_startup(struct irq_data *d)
 {
 	u32 gpionr = irq_to_gpio(d->irq);
 
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index 0aa70eb..8bd8452 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -12,7 +12,7 @@
 
 #include "hpsim_ssc.h"
 
-static unsigned int
+static int
 hpsim_irq_startup(struct irq_data *data)
 {
 	return 0;
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 19f107b..d475ce6 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -381,7 +381,7 @@ iosapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
  * Handlers for level-triggered interrupts.
  */
 
-static unsigned int
+static int
 iosapic_startup_level_irq (struct irq_data *data)
 {
 	unmask_irq(data);
@@ -433,7 +433,7 @@ static struct irq_chip irq_type_iosapic_level = {
  * Handlers for edge-triggered interrupts.
  */
 
-static unsigned int
+static int
 iosapic_startup_edge_irq (struct irq_data *data)
 {
 	unmask_irq(data);
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
index 1b3a776..0734a85 100644
--- a/arch/ia64/kernel/irq_lsapic.c
+++ b/arch/ia64/kernel/irq_lsapic.c
@@ -14,7 +14,7 @@
 #include <linux/sched.h>
 #include <linux/irq.h>
 
-static unsigned int
+static int
 lsapic_noop_startup (struct irq_data *data)
 {
 	return 0;
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 62cf4dd..1e8f972 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -76,7 +76,7 @@ u64 sn_intr_redirect(nasid_t local_nasid, int local_widget,
 	return ret_stuff.status;
 }
 
-static unsigned int sn_startup_irq(struct irq_data *data)
+static int sn_startup_irq(struct irq_data *data)
 {
 	return 0;
 }
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index 17be1e7..0465259 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -4,7 +4,7 @@
 #include <asm/traps.h>
 #include <asm/apollohw.h>
 
-unsigned int apollo_irq_startup(struct irq_data *data)
+int apollo_irq_startup(struct irq_data *data)
 {
 	unsigned int irq = data->irq;
 
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 3e73a63..b784a76 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -82,7 +82,7 @@ __ALIGN_STR "\n\t"
 
 extern void atari_microwire_cmd(int cmd);
 
-static unsigned int atari_irq_startup(struct irq_data *data)
+static int atari_irq_startup(struct irq_data *data)
 {
 	unsigned int irq = data->irq;
 
@@ -190,7 +190,7 @@ static struct irq_chip atari_mfptimer_chip = {
 
 static unsigned char *enat_cpld;
 
-static unsigned int atari_ethernat_startup(struct irq_data *data)
+static int atari_ethernat_startup(struct irq_data *data)
 {
 	int enat_num = 140 - data->irq + 1;
 
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index 81ca118..ac0a036 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -57,8 +57,8 @@
 struct irq_data;
 struct irq_chip;
 struct irq_desc;
-extern unsigned int m68k_irq_startup(struct irq_data *data);
-extern unsigned int m68k_irq_startup_irq(unsigned int irq);
+extern int m68k_irq_startup(struct irq_data *data);
+extern int m68k_irq_startup_irq(unsigned int irq);
 extern void m68k_irq_shutdown(struct irq_data *data);
 extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int,
 						      struct pt_regs *));
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 077d3a7..ecdd6ce 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -125,7 +125,7 @@ void m68k_setup_irq_controller(struct irq_chip *chip,
 	}
 }
 
-unsigned int m68k_irq_startup_irq(unsigned int irq)
+int m68k_irq_startup_irq(unsigned int irq)
 {
 	if (irq <= IRQ_AUTO_7)
 		vectors[VEC_SPUR + irq] = auto_inthandler;
@@ -134,7 +134,7 @@ unsigned int m68k_irq_startup_irq(unsigned int irq)
 	return 0;
 }
 
-unsigned int m68k_irq_startup(struct irq_data *data)
+int m68k_irq_startup(struct irq_data *data)
 {
 	return m68k_irq_startup_irq(data->irq);
 }
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index 5c1a6b2..7ca3a02 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -136,7 +136,7 @@ irqreturn_t mac_debug_handler(int, void *);
 
 /* #define DEBUG_MACINTS */
 
-static unsigned int mac_irq_startup(struct irq_data *);
+static int mac_irq_startup(struct irq_data *);
 static void mac_irq_shutdown(struct irq_data *);
 
 static struct irq_chip mac_irq_chip = {
@@ -254,7 +254,7 @@ void mac_irq_disable(struct irq_data *data)
 	}
 }
 
-static unsigned int mac_irq_startup(struct irq_data *data)
+static int mac_irq_startup(struct irq_data *data)
 {
 	int irq = data->irq;
 
diff --git a/arch/m68k/platform/coldfire/intc-2.c b/arch/m68k/platform/coldfire/intc-2.c
index 9950933..820cbb6 100644
--- a/arch/m68k/platform/coldfire/intc-2.c
+++ b/arch/m68k/platform/coldfire/intc-2.c
@@ -109,7 +109,7 @@ static void intc_irq_ack(struct irq_data *d)
  */
 static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6);
 
-static unsigned int intc_irq_startup(struct irq_data *d)
+static int intc_irq_startup(struct irq_data *d)
 {
 	unsigned int irq = d->irq - MCFINT_VECBASE;
 	unsigned long icraddr;
diff --git a/arch/m68k/platform/coldfire/intc-simr.c b/arch/m68k/platform/coldfire/intc-simr.c
index 7cf2c15..a063489 100644
--- a/arch/m68k/platform/coldfire/intc-simr.c
+++ b/arch/m68k/platform/coldfire/intc-simr.c
@@ -95,7 +95,7 @@ static void intc_irq_ack(struct irq_data *d)
 	__raw_writeb(0x1 << ebit, MCFEPORT_EPFR);
 }
 
-static unsigned int intc_irq_startup(struct irq_data *d)
+static int intc_irq_startup(struct irq_data *d)
 {
 	unsigned int irq = d->irq;
 
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index 513f9bb..dc87a51 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -40,7 +40,7 @@ static void q40_irq_disable(struct irq_data *data);
 unsigned short q40_ablecount[35];
 unsigned short q40_state[35];
 
-static unsigned int q40_irq_startup(struct irq_data *data)
+static int q40_irq_startup(struct irq_data *data)
 {
 	unsigned int irq = data->irq;
 
diff --git a/arch/metag/kernel/irq.c b/arch/metag/kernel/irq.c
index 3b4b7f6..47f6976 100644
--- a/arch/metag/kernel/irq.c
+++ b/arch/metag/kernel/irq.c
@@ -27,7 +27,7 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 
 static struct irq_domain *root_domain;
 
-static unsigned int startup_meta_irq(struct irq_data *data)
+static int startup_meta_irq(struct irq_data *data)
 {
 	tbi_startup_interrupt(data->hwirq);
 	return 0;
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
index 00b798d..13bc81d 100644
--- a/arch/mips/jz4740/gpio.c
+++ b/arch/mips/jz4740/gpio.c
@@ -329,7 +329,7 @@ static void jz_gpio_irq_unmask(struct irq_data *data)
 };
 
 /* TODO: Check if function is gpio */
-static unsigned int jz_gpio_irq_startup(struct irq_data *data)
+static int jz_gpio_irq_startup(struct irq_data *data)
 {
 	jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET);
 	jz_gpio_irq_unmask(data);
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index e498f2b..6b623df 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -62,7 +62,7 @@ static struct irq_chip mips_cpu_irq_controller = {
  * Basically the same as above but taking care of all the MT stuff
  */
 
-static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
+static int mips_mt_cpu_irq_startup(struct irq_data *d)
 {
 	unsigned int vpflags = dvpe();
 
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 85685e1..ccd2554 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -167,7 +167,7 @@ static int ltq_eiu_settype(struct irq_data *d, unsigned int type)
 	return 0;
 }
 
-static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
+static int ltq_startup_eiu_irq(struct irq_data *d)
 {
 	int i;
 
diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c
index 2a1c407..89cf754 100644
--- a/arch/mips/sgi-ip27/ip27-irq-pci.c
+++ b/arch/mips/sgi-ip27/ip27-irq-pci.c
@@ -132,7 +132,7 @@ static int intr_disconnect_level(int cpu, int bit)
 }
 
 /* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int startup_bridge_irq(struct irq_data *d)
+static int startup_bridge_irq(struct irq_data *d)
 {
 	struct bridge_controller *bc;
 	bridgereg_t device;
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 4c24bf6..9824afe 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -143,7 +143,7 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
 /* When an irq gets requested for the first client, if it's an
  * edge interrupt, we clear any previous one on the controller
  */
-static unsigned int pmac_startup_irq(struct irq_data *d)
+static int pmac_startup_irq(struct irq_data *d)
 {
 	unsigned long flags;
 	unsigned int src = irqd_to_hwirq(d);
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c
index 9cd92e6..6f839f0 100644
--- a/arch/powerpc/platforms/wsp/ics.c
+++ b/arch/powerpc/platforms/wsp/ics.c
@@ -295,7 +295,7 @@ static void wsp_chip_unmask_irq(struct irq_data *d)
 	wsp_ics_set_xive(ics, hw_irq, xive);
 }
 
-static unsigned int wsp_chip_startup(struct irq_data *d)
+static int wsp_chip_startup(struct irq_data *d)
 {
 	/* unmask it */
 	wsp_chip_unmask_irq(d);
@@ -720,7 +720,7 @@ static void wsp_ics_msi_unmask_irq(struct irq_data *d)
 	unmask_msi_irq(d);
 }
 
-static unsigned int wsp_ics_msi_startup(struct irq_data *d)
+static int wsp_ics_msi_startup(struct irq_data *d)
 {
 	wsp_ics_msi_unmask_irq(d);
 	return 0;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 8209744..c0fe5a7 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -735,7 +735,7 @@ static void mpic_unmask_ht_irq(struct irq_data *d)
 		mpic_ht_end_irq(mpic, src);
 }
 
-static unsigned int mpic_startup_ht_irq(struct irq_data *d)
+static int mpic_startup_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
 	unsigned int src = irqd_to_hwirq(d);
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
index 3c6ee1b..bd90843 100644
--- a/arch/powerpc/sysdev/xics/ics-opal.c
+++ b/arch/powerpc/sysdev/xics/ics-opal.c
@@ -64,7 +64,7 @@ static void ics_opal_unmask_irq(struct irq_data *d)
 		       __func__, d->irq, hw_irq, server, rc);
 }
 
-static unsigned int ics_opal_startup(struct irq_data *d)
+static int ics_opal_startup(struct irq_data *d)
 {
 #ifdef CONFIG_PCI_MSI
 	/*
diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
index 936575d..2f656e8 100644
--- a/arch/powerpc/sysdev/xics/ics-rtas.c
+++ b/arch/powerpc/sysdev/xics/ics-rtas.c
@@ -67,7 +67,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
 	}
 }
 
-static unsigned int ics_rtas_startup(struct irq_data *d)
+static int ics_rtas_startup(struct irq_data *d)
 {
 #ifdef CONFIG_PCI_MSI
 	/*
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index b7c6897..690c425 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -168,7 +168,7 @@ static void leon_mask_irq(struct irq_data *data)
 	spin_unlock_irqrestore(&leon_irq_lock, flags);
 }
 
-static unsigned int leon_startup_irq(struct irq_data *data)
+static int leon_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	leon_unmask_irq(data);
diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c
index 6df26e3..e4e9423 100644
--- a/arch/sparc/kernel/leon_pci_grpci1.c
+++ b/arch/sparc/kernel/leon_pci_grpci1.c
@@ -337,7 +337,7 @@ static void grpci1_unmask_irq(struct irq_data *data)
 	REGSTORE(priv->regs->irq, REGLOAD(priv->regs->irq) | (1 << irqidx));
 }
 
-static unsigned int grpci1_startup_irq(struct irq_data *data)
+static int grpci1_startup_irq(struct irq_data *data)
 {
 	grpci1_unmask_irq(data);
 	return 0;
diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c
index 5f0402a..5ac51ed 100644
--- a/arch/sparc/kernel/leon_pci_grpci2.c
+++ b/arch/sparc/kernel/leon_pci_grpci2.c
@@ -477,7 +477,7 @@ static void grpci2_unmask_irq(struct irq_data *data)
 	spin_unlock_irqrestore(&grpci2_dev_lock, flags);
 }
 
-static unsigned int grpci2_startup_irq(struct irq_data *data)
+static int grpci2_startup_irq(struct irq_data *data)
 {
 	grpci2_unmask_irq(data);
 	return 0;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 09f4fdd..7abafc2 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -825,7 +825,7 @@ static void pcic_unmask_irq(struct irq_data *data)
 	local_irq_restore(flags);
 }
 
-static unsigned int pcic_startup_irq(struct irq_data *data)
+static int pcic_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	pcic_unmask_irq(data);
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index f8933be..e779239 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -223,7 +223,7 @@ static void sun4d_unmask_irq(struct irq_data *data)
 #endif
 }
 
-static unsigned int sun4d_startup_irq(struct irq_data *data)
+static int sun4d_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	sun4d_unmask_irq(data);
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index c5ade9d..6312a7f 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -220,7 +220,7 @@ static void sun4m_unmask_irq(struct irq_data *data)
 	}
 }
 
-static unsigned int sun4m_startup_irq(struct irq_data *data)
+static int sun4m_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	sun4m_unmask_irq(data);
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index a97a645..a38ec35 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1463,7 +1463,7 @@ static struct pci_ops tile_cfg_ops = {
 
 
 /* MSI support starts here. */
-static unsigned int tilegx_msi_startup(struct irq_data *d)
+static int tilegx_msi_startup(struct irq_data *d)
 {
 	if (d->msi_desc)
 		unmask_msi_irq(d);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 6ad4658..685a344 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2132,7 +2132,7 @@ static int __init timer_irq_works(void)
  * an edge even if it isn't on the 8259A...
  */
 
-static unsigned int startup_ioapic_irq(struct irq_data *data)
+static int startup_ioapic_irq(struct irq_data *data)
 {
 	int was_pending = 0, irq = data->irq;
 	unsigned long flags;
diff --git a/arch/x86/platform/visws/visws_quirks.c b/arch/x86/platform/visws/visws_quirks.c
index 94d8a39..7d537e6 100644
--- a/arch/x86/platform/visws/visws_quirks.c
+++ b/arch/x86/platform/visws/visws_quirks.c
@@ -467,7 +467,7 @@ static struct irq_chip cobalt_irq_type = {
  * interrupt controller type, and through a special virtual interrupt-
  * controller. Device drivers only see the virtual interrupt sources.
  */
-static unsigned int startup_piix4_master_irq(struct irq_data *data)
+static int startup_piix4_master_irq(struct irq_data *data)
 {
 	legacy_pic->init(0);
 	enable_cobalt_irq(data);
diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c
index 6fc6206..e5db9e0 100644
--- a/drivers/gpio/gpio-adnp.c
+++ b/drivers/gpio/gpio-adnp.c
@@ -408,7 +408,7 @@ static void adnp_irq_bus_unlock(struct irq_data *data)
 	mutex_unlock(&adnp->irq_lock);
 }
 
-static unsigned int adnp_irq_startup(struct irq_data *data)
+static int adnp_irq_startup(struct irq_data *data)
 {
 	struct adnp *adnp = irq_data_get_irq_chip_data(data);
 
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
index f32357e..6e99465 100644
--- a/drivers/gpio/gpio-bcm-kona.c
+++ b/drivers/gpio/gpio-bcm-kona.c
@@ -449,7 +449,7 @@ static void bcm_kona_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
-static unsigned int bcm_kona_gpio_irq_startup(struct irq_data *d)
+static int bcm_kona_gpio_irq_startup(struct irq_data *d)
 {
 	struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
index 1e98a98..203f9fa5 100644
--- a/drivers/gpio/gpio-em.c
+++ b/drivers/gpio/gpio-em.c
@@ -99,7 +99,7 @@ static void em_gio_irq_enable(struct irq_data *d)
 	em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d)));
 }
 
-static unsigned int em_gio_irq_startup(struct irq_data *d)
+static int em_gio_irq_startup(struct irq_data *d)
 {
 	struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c
index e585163..7a63536 100644
--- a/drivers/gpio/gpio-intel-mid.c
+++ b/drivers/gpio/gpio-intel-mid.c
@@ -235,7 +235,7 @@ static void intel_mid_irq_mask(struct irq_data *d)
 {
 }
 
-static unsigned int intel_mid_irq_startup(struct irq_data *d)
+static int intel_mid_irq_startup(struct irq_data *d)
 {
 	struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c
index 66b1853..1232df4 100644
--- a/drivers/gpio/gpio-lynxpoint.c
+++ b/drivers/gpio/gpio-lynxpoint.c
@@ -301,7 +301,7 @@ static void lp_irq_disable(struct irq_data *d)
 	spin_unlock_irqrestore(&lg->lock, flags);
 }
 
-static unsigned int lp_irq_startup(struct irq_data *d)
+static int lp_irq_startup(struct irq_data *d)
 {
 	struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
index 1ac288e..326736f 100644
--- a/drivers/gpio/gpio-mcp23s08.c
+++ b/drivers/gpio/gpio-mcp23s08.c
@@ -440,7 +440,7 @@ static void mcp23s08_irq_bus_unlock(struct irq_data *data)
 	mutex_unlock(&mcp->irq_lock);
 }
 
-static unsigned int mcp23s08_irq_startup(struct irq_data *data)
+static int mcp23s08_irq_startup(struct irq_data *data)
 {
 	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
 
diff --git a/drivers/gpio/gpio-tz1090.c b/drivers/gpio/gpio-tz1090.c
index 23e0613..33a086e 100644
--- a/drivers/gpio/gpio-tz1090.c
+++ b/drivers/gpio/gpio-tz1090.c
@@ -302,7 +302,7 @@ static void tz1090_gpio_irq_next_edge(struct tz1090_gpio_bank *bank,
 	__global_unlock2(lstat);
 }
 
-static unsigned int gpio_startup_irq(struct irq_data *data)
+static int gpio_startup_irq(struct irq_data *data)
 {
 	/*
 	 * This warning indicates that the type of the irq hasn't been set
diff --git a/drivers/irqchip/irq-metag.c b/drivers/irqchip/irq-metag.c
index 8e94d7a..12469d6 100644
--- a/drivers/irqchip/irq-metag.c
+++ b/drivers/irqchip/irq-metag.c
@@ -34,7 +34,7 @@ struct metag_internal_irq_priv {
 /* Private data for the one and only internal interrupt controller */
 static struct metag_internal_irq_priv metag_internal_irq_priv;
 
-static unsigned int metag_internal_irq_startup(struct irq_data *data);
+static int metag_internal_irq_startup(struct irq_data *data);
 static void metag_internal_irq_shutdown(struct irq_data *data);
 static void metag_internal_irq_ack(struct irq_data *data);
 static void metag_internal_irq_mask(struct irq_data *data);
@@ -88,7 +88,7 @@ static inline void __iomem *metag_hwvec_addr(irq_hw_number_t hw)
  *	Multiplex interrupts for @irq onto TR1. Clear any pending
  *	interrupts.
  */
-static unsigned int metag_internal_irq_startup(struct irq_data *data)
+static int metag_internal_irq_startup(struct irq_data *data)
 {
 	/* Clear (toggle) the bit in HWSTATMETA for our interrupt. */
 	metag_internal_irq_ack(data);
diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c
index 7a39562..cdcf722 100644
--- a/drivers/pinctrl/pinctrl-adi2.c
+++ b/drivers/pinctrl/pinctrl-adi2.c
@@ -316,7 +316,7 @@ static void adi_gpio_unmask_irq(struct irq_data *d)
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static unsigned int adi_gpio_irq_startup(struct irq_data *d)
+static int adi_gpio_irq_startup(struct irq_data *d)
 {
 	unsigned long flags;
 	struct gpio_port *port = irq_data_get_irq_chip_data(d);
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c
index 665b96b..505a261 100644
--- a/drivers/pinctrl/pinctrl-baytrail.c
+++ b/drivers/pinctrl/pinctrl-baytrail.c
@@ -371,7 +371,7 @@ static void byt_irq_mask(struct irq_data *d)
 {
 }
 
-static unsigned int byt_irq_startup(struct irq_data *d)
+static int byt_irq_startup(struct irq_data *d)
 {
 	struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
index ef2bf31..b1e7333 100644
--- a/drivers/pinctrl/pinctrl-msm.c
+++ b/drivers/pinctrl/pinctrl-msm.c
@@ -805,7 +805,7 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
 	return 0;
 }
 
-static unsigned int msm_gpio_irq_startup(struct irq_data *d)
+static int msm_gpio_irq_startup(struct irq_data *d)
 {
 	struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 53a1111..9c68265 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -844,7 +844,7 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 	return 0;
 }
 
-static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
+static int nmk_gpio_irq_startup(struct irq_data *d)
 {
 	struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c
index a0d6152..89bec51 100644
--- a/drivers/pinctrl/sirf/pinctrl-sirf.c
+++ b/drivers/pinctrl/sirf/pinctrl-sirf.c
@@ -594,7 +594,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
 	return 0;
 }
 
-static unsigned int sirfsoc_gpio_irq_startup(struct irq_data *d)
+static int sirfsoc_gpio_irq_startup(struct irq_data *d)
 {
 	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index f4a9e33..4429ecc 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -520,7 +520,7 @@ static void mask_ack_pirq(struct irq_data *data)
 	eoi_pirq(data);
 }
 
-static unsigned int __startup_pirq(unsigned int irq)
+static int __startup_pirq(unsigned int irq)
 {
 	struct evtchn_bind_pirq bind_pirq;
 	struct irq_info *info = info_for_irq(irq);
@@ -563,7 +563,7 @@ out:
 	return 0;
 }
 
-static unsigned int startup_pirq(struct irq_data *data)
+static int startup_pirq(struct irq_data *data)
 {
 	return __startup_pirq(data->irq);
 }
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 7dc1003..6835778 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -307,7 +307,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
  */
 struct irq_chip {
 	const char	*name;
-	unsigned int	(*irq_startup)(struct irq_data *data);
+	int		(*irq_startup)(struct irq_data *data);
 	void		(*irq_shutdown)(struct irq_data *data);
 	void		(*irq_enable)(struct irq_data *data);
 	void		(*irq_disable)(struct irq_data *data);
diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c
index 988dc58..2994839 100644
--- a/kernel/irq/dummychip.c
+++ b/kernel/irq/dummychip.c
@@ -27,7 +27,7 @@ static void ack_bad(struct irq_data *data)
  */
 static void noop(struct irq_data *data) { }
 
-static unsigned int noop_ret(struct irq_data *data)
+static int noop_ret(struct irq_data *data)
 {
 	return 0;
 }
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-02-27 17:21     ` [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int Jean-Jacques Hiblot
@ 2014-02-28 22:52       ` James Hogan
  2014-03-01 15:31         ` Thomas Gleixner
  2014-03-03  9:22         ` [PATCH v2] " Jean-Jacques Hiblot
  0 siblings, 2 replies; 17+ messages in thread
From: James Hogan @ 2014-02-28 22:52 UTC (permalink / raw)
  To: Jean-Jacques Hiblot
  Cc: tglx, linus.walleij, grant.likely, linux-kernel, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2758 bytes --]

On Thursday 27 February 2014 18:21:19 Jean-Jacques Hiblot wrote:
>  arch/arm/mach-omap2/gpmc.c                | 2 +-
>  arch/blackfin/mach-common/ints-priority.c | 2 +-
>  arch/ia64/hp/sim/hpsim_irq.c              | 2 +-
>  arch/ia64/kernel/iosapic.c                | 4 ++--
>  arch/ia64/kernel/irq_lsapic.c             | 2 +-
>  arch/ia64/sn/kernel/irq.c                 | 2 +-
>  arch/m68k/apollo/dn_ints.c                | 2 +-
>  arch/m68k/atari/ataints.c                 | 4 ++--
>  arch/m68k/include/asm/irq.h               | 4 ++--
>  arch/m68k/kernel/ints.c                   | 4 ++--
>  arch/m68k/mac/macints.c                   | 4 ++--
>  arch/m68k/platform/coldfire/intc-2.c      | 2 +-
>  arch/m68k/platform/coldfire/intc-simr.c   | 2 +-
>  arch/m68k/q40/q40ints.c                   | 2 +-
>  arch/metag/kernel/irq.c                   | 2 +-
>  arch/mips/jz4740/gpio.c                   | 2 +-
>  arch/mips/kernel/irq_cpu.c                | 2 +-
>  arch/mips/lantiq/irq.c                    | 2 +-
>  arch/mips/sgi-ip27/ip27-irq-pci.c         | 2 +-
>  arch/powerpc/platforms/powermac/pic.c     | 2 +-
>  arch/powerpc/platforms/wsp/ics.c          | 4 ++--
>  arch/powerpc/sysdev/mpic.c                | 2 +-
>  arch/powerpc/sysdev/xics/ics-opal.c       | 2 +-
>  arch/powerpc/sysdev/xics/ics-rtas.c       | 2 +-
>  arch/sparc/kernel/leon_kernel.c           | 2 +-
>  arch/sparc/kernel/leon_pci_grpci1.c       | 2 +-
>  arch/sparc/kernel/leon_pci_grpci2.c       | 2 +-
>  arch/sparc/kernel/pcic.c                  | 2 +-
>  arch/sparc/kernel/sun4d_irq.c             | 2 +-
>  arch/sparc/kernel/sun4m_irq.c             | 2 +-
>  arch/tile/kernel/pci_gx.c                 | 2 +-
>  arch/x86/kernel/apic/io_apic.c            | 2 +-
>  arch/x86/platform/visws/visws_quirks.c    | 2 +-
>  drivers/gpio/gpio-adnp.c                  | 2 +-
>  drivers/gpio/gpio-bcm-kona.c              | 2 +-
>  drivers/gpio/gpio-em.c                    | 2 +-
>  drivers/gpio/gpio-intel-mid.c             | 2 +-
>  drivers/gpio/gpio-lynxpoint.c             | 2 +-
>  drivers/gpio/gpio-mcp23s08.c              | 2 +-
>  drivers/gpio/gpio-tz1090.c                | 2 +-
>  drivers/irqchip/irq-metag.c               | 4 ++--

I think you've missed out drivers/irqchip/irq-metag-ext.c

Thanks
James

>  drivers/pinctrl/pinctrl-adi2.c            | 2 +-
>  drivers/pinctrl/pinctrl-baytrail.c        | 2 +-
>  drivers/pinctrl/pinctrl-msm.c             | 2 +-
>  drivers/pinctrl/pinctrl-nomadik.c         | 2 +-
>  drivers/pinctrl/sirf/pinctrl-sirf.c       | 2 +-
>  drivers/xen/events/events_base.c          | 4 ++--
>  include/linux/irq.h                       | 2 +-
>  kernel/irq/dummychip.c                    | 2 +-
>  49 files changed, 57 insertions(+), 57 deletions(-)

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-02-28 22:52       ` James Hogan
@ 2014-03-01 15:31         ` Thomas Gleixner
  2014-03-01 16:01           ` Russell King - ARM Linux
  2014-03-03  9:22         ` [PATCH v2] " Jean-Jacques Hiblot
  1 sibling, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2014-03-01 15:31 UTC (permalink / raw)
  To: James Hogan
  Cc: Jean-Jacques Hiblot, linus.walleij, grant.likely, linux-kernel,
	linux-arm-kernel

On Fri, 28 Feb 2014, James Hogan wrote:
> On Thursday 27 February 2014 18:21:19 Jean-Jacques Hiblot wrote:
> >  drivers/irqchip/irq-metag.c               | 4 ++--
> 
> I think you've missed out drivers/irqchip/irq-metag-ext.c

There is a good reason why I asked to do this with coccinelle.

Thanks,

	tglx


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-03-01 15:31         ` Thomas Gleixner
@ 2014-03-01 16:01           ` Russell King - ARM Linux
  2014-03-03  8:55             ` Jean-Jacques Hiblot
  2014-03-04 10:57             ` Thomas Gleixner
  0 siblings, 2 replies; 17+ messages in thread
From: Russell King - ARM Linux @ 2014-03-01 16:01 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: James Hogan, grant.likely, linus.walleij, Jean-Jacques Hiblot,
	linux-kernel, linux-arm-kernel

On Sat, Mar 01, 2014 at 04:31:13PM +0100, Thomas Gleixner wrote:
> On Fri, 28 Feb 2014, James Hogan wrote:
> > On Thursday 27 February 2014 18:21:19 Jean-Jacques Hiblot wrote:
> > >  drivers/irqchip/irq-metag.c               | 4 ++--
> > 
> > I think you've missed out drivers/irqchip/irq-metag-ext.c
> 
> There is a good reason why I asked to do this with coccinelle.

Go easy, not everyone understands that complex tool - I certainly don't.
I ended up deleting it from my system after several failed attempts, and
I came to the conclusion that to use it properly, you also needed a Julia
installed along side you to learn how to write its scripts.

The big problem is it /doesn't/ do what it advertises to - I ended up
writing expression after expression to make it detect all the various
forms of what I wanted it to, which as I understand the tool is precisely
the opposite of what you're supposed to do with it.

I ended up coming to the conclusion that a well formed sed and/or grep
expression was far more useful and effective than trying to figure out
coccinelle.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-03-01 16:01           ` Russell King - ARM Linux
@ 2014-03-03  8:55             ` Jean-Jacques Hiblot
  2014-03-04 10:57             ` Thomas Gleixner
  1 sibling, 0 replies; 17+ messages in thread
From: Jean-Jacques Hiblot @ 2014-03-03  8:55 UTC (permalink / raw)
  To: Russell King - ARM Linux, Thomas Gleixner
  Cc: James Hogan, grant.likely, linus.walleij, Jean-Jacques Hiblot,
	linux-kernel, linux-arm-kernel



Le 01/03/2014 17:01, Russell King - ARM Linux a écrit :
> On Sat, Mar 01, 2014 at 04:31:13PM +0100, Thomas Gleixner wrote:
>> On Fri, 28 Feb 2014, James Hogan wrote:
>>> On Thursday 27 February 2014 18:21:19 Jean-Jacques Hiblot wrote:
>>>>   drivers/irqchip/irq-metag.c               | 4 ++--
>>>
>>> I think you've missed out drivers/irqchip/irq-metag-ext.c
>>
>> There is a good reason why I asked to do this with coccinelle.
>
> Go easy, not everyone understands that complex tool - I certainly don't.
> I ended up deleting it from my system after several failed attempts, and
> I came to the conclusion that to use it properly, you also needed a Julia
> installed along side you to learn how to write its scripts.
>
> The big problem is it /doesn't/ do what it advertises to - I ended up
> writing expression after expression to make it detect all the various
> forms of what I wanted it to, which as I understand the tool is precisely
> the opposite of what you're supposed to do with it.
>
> I ended up coming to the conclusion that a well formed sed and/or grep
> expression was far more useful and effective than trying to figure out
> coccinelle.
>
Actually I tried to use coccinelle for this, but to paraphrase Thomas: 
it was a failure on its own. The tool is complex.
I'll send shortly a second version of the patch with the missing change(s).

Jean-Jacques

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-02-28 22:52       ` James Hogan
  2014-03-01 15:31         ` Thomas Gleixner
@ 2014-03-03  9:22         ` Jean-Jacques Hiblot
  1 sibling, 0 replies; 17+ messages in thread
From: Jean-Jacques Hiblot @ 2014-03-03  9:22 UTC (permalink / raw)
  To: tglx
  Cc: linus.walleij, grant.likely, linux-kernel, linux-arm-kernel,
	james.hogan, Jean-Jacques Hiblot

This patch changes the return type of the irq_startup() callback in irq_chip
from unsigned int to int, and modify the IRQ drivers providing this feature.
This allows the callback to return negative error codes.
This patch prepares the way for another patch that'll make request_irq() fail
when irq_startup() fails.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
---

Changes since v1:
 * changed in drivers/irqchip/irq-orion.c
 * changed in drivers/irqchip/irq-metag-ext.c
 
 arch/arm/mach-omap2/gpmc.c                | 2 +-
 arch/blackfin/mach-common/ints-priority.c | 2 +-
 arch/ia64/hp/sim/hpsim_irq.c              | 2 +-
 arch/ia64/kernel/iosapic.c                | 4 ++--
 arch/ia64/kernel/irq_lsapic.c             | 2 +-
 arch/ia64/sn/kernel/irq.c                 | 2 +-
 arch/m68k/apollo/dn_ints.c                | 2 +-
 arch/m68k/atari/ataints.c                 | 4 ++--
 arch/m68k/include/asm/irq.h               | 4 ++--
 arch/m68k/kernel/ints.c                   | 4 ++--
 arch/m68k/mac/macints.c                   | 4 ++--
 arch/m68k/platform/coldfire/intc-2.c      | 2 +-
 arch/m68k/platform/coldfire/intc-simr.c   | 2 +-
 arch/m68k/q40/q40ints.c                   | 2 +-
 arch/metag/kernel/irq.c                   | 2 +-
 arch/mips/jz4740/gpio.c                   | 2 +-
 arch/mips/kernel/irq_cpu.c                | 2 +-
 arch/mips/lantiq/irq.c                    | 2 +-
 arch/mips/sgi-ip27/ip27-irq-pci.c         | 2 +-
 arch/powerpc/platforms/powermac/pic.c     | 2 +-
 arch/powerpc/platforms/wsp/ics.c          | 4 ++--
 arch/powerpc/sysdev/mpic.c                | 2 +-
 arch/powerpc/sysdev/xics/ics-opal.c       | 2 +-
 arch/powerpc/sysdev/xics/ics-rtas.c       | 2 +-
 arch/sparc/kernel/leon_kernel.c           | 2 +-
 arch/sparc/kernel/leon_pci_grpci1.c       | 2 +-
 arch/sparc/kernel/leon_pci_grpci2.c       | 2 +-
 arch/sparc/kernel/pcic.c                  | 2 +-
 arch/sparc/kernel/sun4d_irq.c             | 2 +-
 arch/sparc/kernel/sun4m_irq.c             | 2 +-
 arch/tile/kernel/pci_gx.c                 | 2 +-
 arch/x86/kernel/apic/io_apic.c            | 2 +-
 arch/x86/platform/visws/visws_quirks.c    | 2 +-
 drivers/gpio/gpio-adnp.c                  | 2 +-
 drivers/gpio/gpio-bcm-kona.c              | 2 +-
 drivers/gpio/gpio-em.c                    | 2 +-
 drivers/gpio/gpio-intel-mid.c             | 2 +-
 drivers/gpio/gpio-lynxpoint.c             | 2 +-
 drivers/gpio/gpio-mcp23s08.c              | 2 +-
 drivers/gpio/gpio-tz1090.c                | 2 +-
 drivers/irqchip/irq-metag-ext.c           | 2 +-
 drivers/irqchip/irq-metag.c               | 4 ++--
 drivers/irqchip/irq-orion.c               | 2 +-
 drivers/pinctrl/pinctrl-adi2.c            | 2 +-
 drivers/pinctrl/pinctrl-baytrail.c        | 2 +-
 drivers/pinctrl/pinctrl-msm.c             | 2 +-
 drivers/pinctrl/pinctrl-nomadik.c         | 2 +-
 drivers/pinctrl/sirf/pinctrl-sirf.c       | 2 +-
 drivers/xen/events/events_base.c          | 4 ++--
 include/linux/irq.h                       | 2 +-
 kernel/irq/dummychip.c                    | 2 +-
 51 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index ab43755..1c905e4 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -714,7 +714,7 @@ static void gpmc_irq_enable(struct irq_data *p)
 
 static void gpmc_irq_noop(struct irq_data *data) { }
 
-static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
+static int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
 
 static int gpmc_setup_irq(void)
 {
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 867b7ce..9a25b64 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -734,7 +734,7 @@ static void bfin_gpio_unmask_irq(struct irq_data *d)
 	set_gpio_maska(irq_to_gpio(d->irq), 1);
 }
 
-static unsigned int bfin_gpio_irq_startup(struct irq_data *d)
+static int bfin_gpio_irq_startup(struct irq_data *d)
 {
 	u32 gpionr = irq_to_gpio(d->irq);
 
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index 0aa70eb..8bd8452 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -12,7 +12,7 @@
 
 #include "hpsim_ssc.h"
 
-static unsigned int
+static int
 hpsim_irq_startup(struct irq_data *data)
 {
 	return 0;
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 19f107b..d475ce6 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -381,7 +381,7 @@ iosapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
  * Handlers for level-triggered interrupts.
  */
 
-static unsigned int
+static int
 iosapic_startup_level_irq (struct irq_data *data)
 {
 	unmask_irq(data);
@@ -433,7 +433,7 @@ static struct irq_chip irq_type_iosapic_level = {
  * Handlers for edge-triggered interrupts.
  */
 
-static unsigned int
+static int
 iosapic_startup_edge_irq (struct irq_data *data)
 {
 	unmask_irq(data);
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
index 1b3a776..0734a85 100644
--- a/arch/ia64/kernel/irq_lsapic.c
+++ b/arch/ia64/kernel/irq_lsapic.c
@@ -14,7 +14,7 @@
 #include <linux/sched.h>
 #include <linux/irq.h>
 
-static unsigned int
+static int
 lsapic_noop_startup (struct irq_data *data)
 {
 	return 0;
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 62cf4dd..1e8f972 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -76,7 +76,7 @@ u64 sn_intr_redirect(nasid_t local_nasid, int local_widget,
 	return ret_stuff.status;
 }
 
-static unsigned int sn_startup_irq(struct irq_data *data)
+static int sn_startup_irq(struct irq_data *data)
 {
 	return 0;
 }
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index 17be1e7..0465259 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -4,7 +4,7 @@
 #include <asm/traps.h>
 #include <asm/apollohw.h>
 
-unsigned int apollo_irq_startup(struct irq_data *data)
+int apollo_irq_startup(struct irq_data *data)
 {
 	unsigned int irq = data->irq;
 
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 3e73a63..b784a76 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -82,7 +82,7 @@ __ALIGN_STR "\n\t"
 
 extern void atari_microwire_cmd(int cmd);
 
-static unsigned int atari_irq_startup(struct irq_data *data)
+static int atari_irq_startup(struct irq_data *data)
 {
 	unsigned int irq = data->irq;
 
@@ -190,7 +190,7 @@ static struct irq_chip atari_mfptimer_chip = {
 
 static unsigned char *enat_cpld;
 
-static unsigned int atari_ethernat_startup(struct irq_data *data)
+static int atari_ethernat_startup(struct irq_data *data)
 {
 	int enat_num = 140 - data->irq + 1;
 
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index 81ca118..ac0a036 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -57,8 +57,8 @@
 struct irq_data;
 struct irq_chip;
 struct irq_desc;
-extern unsigned int m68k_irq_startup(struct irq_data *data);
-extern unsigned int m68k_irq_startup_irq(unsigned int irq);
+extern int m68k_irq_startup(struct irq_data *data);
+extern int m68k_irq_startup_irq(unsigned int irq);
 extern void m68k_irq_shutdown(struct irq_data *data);
 extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int,
 						      struct pt_regs *));
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 077d3a7..ecdd6ce 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -125,7 +125,7 @@ void m68k_setup_irq_controller(struct irq_chip *chip,
 	}
 }
 
-unsigned int m68k_irq_startup_irq(unsigned int irq)
+int m68k_irq_startup_irq(unsigned int irq)
 {
 	if (irq <= IRQ_AUTO_7)
 		vectors[VEC_SPUR + irq] = auto_inthandler;
@@ -134,7 +134,7 @@ unsigned int m68k_irq_startup_irq(unsigned int irq)
 	return 0;
 }
 
-unsigned int m68k_irq_startup(struct irq_data *data)
+int m68k_irq_startup(struct irq_data *data)
 {
 	return m68k_irq_startup_irq(data->irq);
 }
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index 5c1a6b2..7ca3a02 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -136,7 +136,7 @@ irqreturn_t mac_debug_handler(int, void *);
 
 /* #define DEBUG_MACINTS */
 
-static unsigned int mac_irq_startup(struct irq_data *);
+static int mac_irq_startup(struct irq_data *);
 static void mac_irq_shutdown(struct irq_data *);
 
 static struct irq_chip mac_irq_chip = {
@@ -254,7 +254,7 @@ void mac_irq_disable(struct irq_data *data)
 	}
 }
 
-static unsigned int mac_irq_startup(struct irq_data *data)
+static int mac_irq_startup(struct irq_data *data)
 {
 	int irq = data->irq;
 
diff --git a/arch/m68k/platform/coldfire/intc-2.c b/arch/m68k/platform/coldfire/intc-2.c
index 9950933..820cbb6 100644
--- a/arch/m68k/platform/coldfire/intc-2.c
+++ b/arch/m68k/platform/coldfire/intc-2.c
@@ -109,7 +109,7 @@ static void intc_irq_ack(struct irq_data *d)
  */
 static u8 intc_intpri = MCFSIM_ICR_LEVEL(6) | MCFSIM_ICR_PRI(6);
 
-static unsigned int intc_irq_startup(struct irq_data *d)
+static int intc_irq_startup(struct irq_data *d)
 {
 	unsigned int irq = d->irq - MCFINT_VECBASE;
 	unsigned long icraddr;
diff --git a/arch/m68k/platform/coldfire/intc-simr.c b/arch/m68k/platform/coldfire/intc-simr.c
index 7cf2c15..a063489 100644
--- a/arch/m68k/platform/coldfire/intc-simr.c
+++ b/arch/m68k/platform/coldfire/intc-simr.c
@@ -95,7 +95,7 @@ static void intc_irq_ack(struct irq_data *d)
 	__raw_writeb(0x1 << ebit, MCFEPORT_EPFR);
 }
 
-static unsigned int intc_irq_startup(struct irq_data *d)
+static int intc_irq_startup(struct irq_data *d)
 {
 	unsigned int irq = d->irq;
 
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index 513f9bb..dc87a51 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -40,7 +40,7 @@ static void q40_irq_disable(struct irq_data *data);
 unsigned short q40_ablecount[35];
 unsigned short q40_state[35];
 
-static unsigned int q40_irq_startup(struct irq_data *data)
+static int q40_irq_startup(struct irq_data *data)
 {
 	unsigned int irq = data->irq;
 
diff --git a/arch/metag/kernel/irq.c b/arch/metag/kernel/irq.c
index 3b4b7f6..47f6976 100644
--- a/arch/metag/kernel/irq.c
+++ b/arch/metag/kernel/irq.c
@@ -27,7 +27,7 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 
 static struct irq_domain *root_domain;
 
-static unsigned int startup_meta_irq(struct irq_data *data)
+static int startup_meta_irq(struct irq_data *data)
 {
 	tbi_startup_interrupt(data->hwirq);
 	return 0;
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
index 00b798d..13bc81d 100644
--- a/arch/mips/jz4740/gpio.c
+++ b/arch/mips/jz4740/gpio.c
@@ -329,7 +329,7 @@ static void jz_gpio_irq_unmask(struct irq_data *data)
 };
 
 /* TODO: Check if function is gpio */
-static unsigned int jz_gpio_irq_startup(struct irq_data *data)
+static int jz_gpio_irq_startup(struct irq_data *data)
 {
 	jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET);
 	jz_gpio_irq_unmask(data);
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index e498f2b..6b623df 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -62,7 +62,7 @@ static struct irq_chip mips_cpu_irq_controller = {
  * Basically the same as above but taking care of all the MT stuff
  */
 
-static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
+static int mips_mt_cpu_irq_startup(struct irq_data *d)
 {
 	unsigned int vpflags = dvpe();
 
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 85685e1..ccd2554 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -167,7 +167,7 @@ static int ltq_eiu_settype(struct irq_data *d, unsigned int type)
 	return 0;
 }
 
-static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
+static int ltq_startup_eiu_irq(struct irq_data *d)
 {
 	int i;
 
diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c
index 2a1c407..89cf754 100644
--- a/arch/mips/sgi-ip27/ip27-irq-pci.c
+++ b/arch/mips/sgi-ip27/ip27-irq-pci.c
@@ -132,7 +132,7 @@ static int intr_disconnect_level(int cpu, int bit)
 }
 
 /* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int startup_bridge_irq(struct irq_data *d)
+static int startup_bridge_irq(struct irq_data *d)
 {
 	struct bridge_controller *bc;
 	bridgereg_t device;
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 4c24bf6..9824afe 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -143,7 +143,7 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
 /* When an irq gets requested for the first client, if it's an
  * edge interrupt, we clear any previous one on the controller
  */
-static unsigned int pmac_startup_irq(struct irq_data *d)
+static int pmac_startup_irq(struct irq_data *d)
 {
 	unsigned long flags;
 	unsigned int src = irqd_to_hwirq(d);
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c
index 9cd92e6..6f839f0 100644
--- a/arch/powerpc/platforms/wsp/ics.c
+++ b/arch/powerpc/platforms/wsp/ics.c
@@ -295,7 +295,7 @@ static void wsp_chip_unmask_irq(struct irq_data *d)
 	wsp_ics_set_xive(ics, hw_irq, xive);
 }
 
-static unsigned int wsp_chip_startup(struct irq_data *d)
+static int wsp_chip_startup(struct irq_data *d)
 {
 	/* unmask it */
 	wsp_chip_unmask_irq(d);
@@ -720,7 +720,7 @@ static void wsp_ics_msi_unmask_irq(struct irq_data *d)
 	unmask_msi_irq(d);
 }
 
-static unsigned int wsp_ics_msi_startup(struct irq_data *d)
+static int wsp_ics_msi_startup(struct irq_data *d)
 {
 	wsp_ics_msi_unmask_irq(d);
 	return 0;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 8209744..c0fe5a7 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -735,7 +735,7 @@ static void mpic_unmask_ht_irq(struct irq_data *d)
 		mpic_ht_end_irq(mpic, src);
 }
 
-static unsigned int mpic_startup_ht_irq(struct irq_data *d)
+static int mpic_startup_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
 	unsigned int src = irqd_to_hwirq(d);
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
index 3c6ee1b..bd90843 100644
--- a/arch/powerpc/sysdev/xics/ics-opal.c
+++ b/arch/powerpc/sysdev/xics/ics-opal.c
@@ -64,7 +64,7 @@ static void ics_opal_unmask_irq(struct irq_data *d)
 		       __func__, d->irq, hw_irq, server, rc);
 }
 
-static unsigned int ics_opal_startup(struct irq_data *d)
+static int ics_opal_startup(struct irq_data *d)
 {
 #ifdef CONFIG_PCI_MSI
 	/*
diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
index 936575d..2f656e8 100644
--- a/arch/powerpc/sysdev/xics/ics-rtas.c
+++ b/arch/powerpc/sysdev/xics/ics-rtas.c
@@ -67,7 +67,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
 	}
 }
 
-static unsigned int ics_rtas_startup(struct irq_data *d)
+static int ics_rtas_startup(struct irq_data *d)
 {
 #ifdef CONFIG_PCI_MSI
 	/*
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index b7c6897..690c425 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -168,7 +168,7 @@ static void leon_mask_irq(struct irq_data *data)
 	spin_unlock_irqrestore(&leon_irq_lock, flags);
 }
 
-static unsigned int leon_startup_irq(struct irq_data *data)
+static int leon_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	leon_unmask_irq(data);
diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c
index 6df26e3..e4e9423 100644
--- a/arch/sparc/kernel/leon_pci_grpci1.c
+++ b/arch/sparc/kernel/leon_pci_grpci1.c
@@ -337,7 +337,7 @@ static void grpci1_unmask_irq(struct irq_data *data)
 	REGSTORE(priv->regs->irq, REGLOAD(priv->regs->irq) | (1 << irqidx));
 }
 
-static unsigned int grpci1_startup_irq(struct irq_data *data)
+static int grpci1_startup_irq(struct irq_data *data)
 {
 	grpci1_unmask_irq(data);
 	return 0;
diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c
index 5f0402a..5ac51ed 100644
--- a/arch/sparc/kernel/leon_pci_grpci2.c
+++ b/arch/sparc/kernel/leon_pci_grpci2.c
@@ -477,7 +477,7 @@ static void grpci2_unmask_irq(struct irq_data *data)
 	spin_unlock_irqrestore(&grpci2_dev_lock, flags);
 }
 
-static unsigned int grpci2_startup_irq(struct irq_data *data)
+static int grpci2_startup_irq(struct irq_data *data)
 {
 	grpci2_unmask_irq(data);
 	return 0;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 09f4fdd..7abafc2 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -825,7 +825,7 @@ static void pcic_unmask_irq(struct irq_data *data)
 	local_irq_restore(flags);
 }
 
-static unsigned int pcic_startup_irq(struct irq_data *data)
+static int pcic_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	pcic_unmask_irq(data);
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index f8933be..e779239 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -223,7 +223,7 @@ static void sun4d_unmask_irq(struct irq_data *data)
 #endif
 }
 
-static unsigned int sun4d_startup_irq(struct irq_data *data)
+static int sun4d_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	sun4d_unmask_irq(data);
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index c5ade9d..6312a7f 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -220,7 +220,7 @@ static void sun4m_unmask_irq(struct irq_data *data)
 	}
 }
 
-static unsigned int sun4m_startup_irq(struct irq_data *data)
+static int sun4m_startup_irq(struct irq_data *data)
 {
 	irq_link(data->irq);
 	sun4m_unmask_irq(data);
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index a97a645..a38ec35 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1463,7 +1463,7 @@ static struct pci_ops tile_cfg_ops = {
 
 
 /* MSI support starts here. */
-static unsigned int tilegx_msi_startup(struct irq_data *d)
+static int tilegx_msi_startup(struct irq_data *d)
 {
 	if (d->msi_desc)
 		unmask_msi_irq(d);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 6ad4658..685a344 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2132,7 +2132,7 @@ static int __init timer_irq_works(void)
  * an edge even if it isn't on the 8259A...
  */
 
-static unsigned int startup_ioapic_irq(struct irq_data *data)
+static int startup_ioapic_irq(struct irq_data *data)
 {
 	int was_pending = 0, irq = data->irq;
 	unsigned long flags;
diff --git a/arch/x86/platform/visws/visws_quirks.c b/arch/x86/platform/visws/visws_quirks.c
index 94d8a39..7d537e6 100644
--- a/arch/x86/platform/visws/visws_quirks.c
+++ b/arch/x86/platform/visws/visws_quirks.c
@@ -467,7 +467,7 @@ static struct irq_chip cobalt_irq_type = {
  * interrupt controller type, and through a special virtual interrupt-
  * controller. Device drivers only see the virtual interrupt sources.
  */
-static unsigned int startup_piix4_master_irq(struct irq_data *data)
+static int startup_piix4_master_irq(struct irq_data *data)
 {
 	legacy_pic->init(0);
 	enable_cobalt_irq(data);
diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c
index 6fc6206..e5db9e0 100644
--- a/drivers/gpio/gpio-adnp.c
+++ b/drivers/gpio/gpio-adnp.c
@@ -408,7 +408,7 @@ static void adnp_irq_bus_unlock(struct irq_data *data)
 	mutex_unlock(&adnp->irq_lock);
 }
 
-static unsigned int adnp_irq_startup(struct irq_data *data)
+static int adnp_irq_startup(struct irq_data *data)
 {
 	struct adnp *adnp = irq_data_get_irq_chip_data(data);
 
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
index f32357e..6e99465 100644
--- a/drivers/gpio/gpio-bcm-kona.c
+++ b/drivers/gpio/gpio-bcm-kona.c
@@ -449,7 +449,7 @@ static void bcm_kona_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
-static unsigned int bcm_kona_gpio_irq_startup(struct irq_data *d)
+static int bcm_kona_gpio_irq_startup(struct irq_data *d)
 {
 	struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
index 1e98a98..203f9fa5 100644
--- a/drivers/gpio/gpio-em.c
+++ b/drivers/gpio/gpio-em.c
@@ -99,7 +99,7 @@ static void em_gio_irq_enable(struct irq_data *d)
 	em_gio_write(p, GIO_IEN, BIT(irqd_to_hwirq(d)));
 }
 
-static unsigned int em_gio_irq_startup(struct irq_data *d)
+static int em_gio_irq_startup(struct irq_data *d)
 {
 	struct em_gio_priv *p = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c
index e585163..7a63536 100644
--- a/drivers/gpio/gpio-intel-mid.c
+++ b/drivers/gpio/gpio-intel-mid.c
@@ -235,7 +235,7 @@ static void intel_mid_irq_mask(struct irq_data *d)
 {
 }
 
-static unsigned int intel_mid_irq_startup(struct irq_data *d)
+static int intel_mid_irq_startup(struct irq_data *d)
 {
 	struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c
index 66b1853..1232df4 100644
--- a/drivers/gpio/gpio-lynxpoint.c
+++ b/drivers/gpio/gpio-lynxpoint.c
@@ -301,7 +301,7 @@ static void lp_irq_disable(struct irq_data *d)
 	spin_unlock_irqrestore(&lg->lock, flags);
 }
 
-static unsigned int lp_irq_startup(struct irq_data *d)
+static int lp_irq_startup(struct irq_data *d)
 {
 	struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
index 1ac288e..326736f 100644
--- a/drivers/gpio/gpio-mcp23s08.c
+++ b/drivers/gpio/gpio-mcp23s08.c
@@ -440,7 +440,7 @@ static void mcp23s08_irq_bus_unlock(struct irq_data *data)
 	mutex_unlock(&mcp->irq_lock);
 }
 
-static unsigned int mcp23s08_irq_startup(struct irq_data *data)
+static int mcp23s08_irq_startup(struct irq_data *data)
 {
 	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
 
diff --git a/drivers/gpio/gpio-tz1090.c b/drivers/gpio/gpio-tz1090.c
index 23e0613..33a086e 100644
--- a/drivers/gpio/gpio-tz1090.c
+++ b/drivers/gpio/gpio-tz1090.c
@@ -302,7 +302,7 @@ static void tz1090_gpio_irq_next_edge(struct tz1090_gpio_bank *bank,
 	__global_unlock2(lstat);
 }
 
-static unsigned int gpio_startup_irq(struct irq_data *data)
+static int gpio_startup_irq(struct irq_data *data)
 {
 	/*
 	 * This warning indicates that the type of the irq hasn't been set
diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c
index 2cb474a..94e78fd 100644
--- a/drivers/irqchip/irq-metag-ext.c
+++ b/drivers/irqchip/irq-metag-ext.c
@@ -127,7 +127,7 @@ static inline void __iomem *meta_intc_vec_addr(irq_hw_number_t hw)
  * Multiplex interrupts for irq onto TR2. Clear any pending interrupts and
  * unmask irq, both using the appropriate callbacks.
  */
-static unsigned int meta_intc_startup_irq(struct irq_data *data)
+static int meta_intc_startup_irq(struct irq_data *data)
 {
 	irq_hw_number_t hw = data->hwirq;
 	void __iomem *vec_addr = meta_intc_vec_addr(hw);
diff --git a/drivers/irqchip/irq-metag.c b/drivers/irqchip/irq-metag.c
index c16c186..101bc15 100644
--- a/drivers/irqchip/irq-metag.c
+++ b/drivers/irqchip/irq-metag.c
@@ -34,7 +34,7 @@ struct metag_internal_irq_priv {
 /* Private data for the one and only internal interrupt controller */
 static struct metag_internal_irq_priv metag_internal_irq_priv;
 
-static unsigned int metag_internal_irq_startup(struct irq_data *data);
+static int metag_internal_irq_startup(struct irq_data *data);
 static void metag_internal_irq_shutdown(struct irq_data *data);
 static void metag_internal_irq_ack(struct irq_data *data);
 static void metag_internal_irq_mask(struct irq_data *data);
@@ -88,7 +88,7 @@ static inline void __iomem *metag_hwvec_addr(irq_hw_number_t hw)
  *	Multiplex interrupts for @irq onto TR1. Clear any pending
  *	interrupts.
  */
-static unsigned int metag_internal_irq_startup(struct irq_data *data)
+static int metag_internal_irq_startup(struct irq_data *data)
 {
 	/* Clear (toggle) the bit in HWSTATMETA for our interrupt. */
 	metag_internal_irq_ack(data);
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c
index 8e41be6..a9e46ef 100644
--- a/drivers/irqchip/irq-orion.c
+++ b/drivers/irqchip/irq-orion.c
@@ -128,7 +128,7 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc)
  * Bridge IRQ_CAUSE is asserted regardless of IRQ_MASK register.
  * To avoid interrupt events on stale irqs, we clear them before unmask.
  */
-static unsigned int orion_bridge_irq_startup(struct irq_data *d)
+static int orion_bridge_irq_startup(struct irq_data *d)
 {
 	struct irq_chip_type *ct = irq_data_get_chip_type(d);
 
diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c
index 7a39562..cdcf722 100644
--- a/drivers/pinctrl/pinctrl-adi2.c
+++ b/drivers/pinctrl/pinctrl-adi2.c
@@ -316,7 +316,7 @@ static void adi_gpio_unmask_irq(struct irq_data *d)
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static unsigned int adi_gpio_irq_startup(struct irq_data *d)
+static int adi_gpio_irq_startup(struct irq_data *d)
 {
 	unsigned long flags;
 	struct gpio_port *port = irq_data_get_irq_chip_data(d);
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c
index 665b96b..505a261 100644
--- a/drivers/pinctrl/pinctrl-baytrail.c
+++ b/drivers/pinctrl/pinctrl-baytrail.c
@@ -371,7 +371,7 @@ static void byt_irq_mask(struct irq_data *d)
 {
 }
 
-static unsigned int byt_irq_startup(struct irq_data *d)
+static int byt_irq_startup(struct irq_data *d)
 {
 	struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
index ef2bf31..b1e7333 100644
--- a/drivers/pinctrl/pinctrl-msm.c
+++ b/drivers/pinctrl/pinctrl-msm.c
@@ -805,7 +805,7 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
 	return 0;
 }
 
-static unsigned int msm_gpio_irq_startup(struct irq_data *d)
+static int msm_gpio_irq_startup(struct irq_data *d)
 {
 	struct msm_pinctrl *pctrl = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 53a1111..9c68265 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -844,7 +844,7 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 	return 0;
 }
 
-static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
+static int nmk_gpio_irq_startup(struct irq_data *d)
 {
 	struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c
index a0d6152..89bec51 100644
--- a/drivers/pinctrl/sirf/pinctrl-sirf.c
+++ b/drivers/pinctrl/sirf/pinctrl-sirf.c
@@ -594,7 +594,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
 	return 0;
 }
 
-static unsigned int sirfsoc_gpio_irq_startup(struct irq_data *d)
+static int sirfsoc_gpio_irq_startup(struct irq_data *d)
 {
 	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
 
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index f4a9e33..4429ecc 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -520,7 +520,7 @@ static void mask_ack_pirq(struct irq_data *data)
 	eoi_pirq(data);
 }
 
-static unsigned int __startup_pirq(unsigned int irq)
+static int __startup_pirq(unsigned int irq)
 {
 	struct evtchn_bind_pirq bind_pirq;
 	struct irq_info *info = info_for_irq(irq);
@@ -563,7 +563,7 @@ out:
 	return 0;
 }
 
-static unsigned int startup_pirq(struct irq_data *data)
+static int startup_pirq(struct irq_data *data)
 {
 	return __startup_pirq(data->irq);
 }
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 7dc1003..6835778 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -307,7 +307,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
  */
 struct irq_chip {
 	const char	*name;
-	unsigned int	(*irq_startup)(struct irq_data *data);
+	int		(*irq_startup)(struct irq_data *data);
 	void		(*irq_shutdown)(struct irq_data *data);
 	void		(*irq_enable)(struct irq_data *data);
 	void		(*irq_disable)(struct irq_data *data);
diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c
index 988dc58..2994839 100644
--- a/kernel/irq/dummychip.c
+++ b/kernel/irq/dummychip.c
@@ -27,7 +27,7 @@ static void ack_bad(struct irq_data *data)
  */
 static void noop(struct irq_data *data) { }
 
-static unsigned int noop_ret(struct irq_data *data)
+static int noop_ret(struct irq_data *data)
 {
 	return 0;
 }
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-03-01 16:01           ` Russell King - ARM Linux
  2014-03-03  8:55             ` Jean-Jacques Hiblot
@ 2014-03-04 10:57             ` Thomas Gleixner
  2014-03-04 11:14               ` James Hogan
  1 sibling, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2014-03-04 10:57 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: James Hogan, grant.likely, linus.walleij, Jean-Jacques Hiblot,
	linux-kernel, linux-arm-kernel

On Sat, 1 Mar 2014, Russell King - ARM Linux wrote:

> On Sat, Mar 01, 2014 at 04:31:13PM +0100, Thomas Gleixner wrote:
> > On Fri, 28 Feb 2014, James Hogan wrote:
> > > On Thursday 27 February 2014 18:21:19 Jean-Jacques Hiblot wrote:
> > > >  drivers/irqchip/irq-metag.c               | 4 ++--
> > > 
> > > I think you've missed out drivers/irqchip/irq-metag-ext.c
> > 
> > There is a good reason why I asked to do this with coccinelle.
> 
> Go easy, not everyone understands that complex tool - I certainly don't.
> I ended up deleting it from my system after several failed attempts, and
> I came to the conclusion that to use it properly, you also needed a Julia
> installed along side you to learn how to write its scripts.

The trick is to send your incomplete script with an explanation what
it should do to the cocci mailinglist. Julia and the other folks are
always happy to help. :)

But seriously, I whipped up a cocci script to verify James patch and
yes it found all occurences except one in drivers/gpio/gpio-tz1090.c

The reason is the usage of commata instead of semicolons. You can work
around that with cocci, but that gets ugly ....

Thanks,

	tglx

--- a/drivers/gpio/gpio-tz1090.c
+++ b/drivers/gpio/gpio-tz1090.c
@@ -488,26 +488,26 @@ static int tz1090_gpio_bank_probe(struct tz1090_gpio_bank_info *info)
 	gc->chip_types[0].handler		= handle_level_irq;
 	gc->chip_types[0].regs.ack		= REG_GPIO_IRQ_STS;
 	gc->chip_types[0].regs.mask		= REG_GPIO_IRQ_EN;
-	gc->chip_types[0].chip.irq_startup	= gpio_startup_irq,
-	gc->chip_types[0].chip.irq_ack		= irq_gc_ack_clr_bit,
-	gc->chip_types[0].chip.irq_mask		= irq_gc_mask_clr_bit,
-	gc->chip_types[0].chip.irq_unmask	= irq_gc_mask_set_bit,
-	gc->chip_types[0].chip.irq_set_type	= gpio_set_irq_type,
-	gc->chip_types[0].chip.irq_set_wake	= gpio_set_irq_wake,
-	gc->chip_types[0].chip.flags		= IRQCHIP_MASK_ON_SUSPEND,
+	gc->chip_types[0].chip.irq_startup	= gpio_startup_irq;
+	gc->chip_types[0].chip.irq_ack		= irq_gc_ack_clr_bit;
+	gc->chip_types[0].chip.irq_mask		= irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask	= irq_gc_mask_set_bit;
+	gc->chip_types[0].chip.irq_set_type	= gpio_set_irq_type;
+	gc->chip_types[0].chip.irq_set_wake	= gpio_set_irq_wake;
+	gc->chip_types[0].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
 
 	/* edge chip type */
 	gc->chip_types[1].type			= IRQ_TYPE_EDGE_BOTH;
 	gc->chip_types[1].handler		= handle_edge_irq;
 	gc->chip_types[1].regs.ack		= REG_GPIO_IRQ_STS;
 	gc->chip_types[1].regs.mask		= REG_GPIO_IRQ_EN;
-	gc->chip_types[1].chip.irq_startup	= gpio_startup_irq,
-	gc->chip_types[1].chip.irq_ack		= irq_gc_ack_clr_bit,
-	gc->chip_types[1].chip.irq_mask		= irq_gc_mask_clr_bit,
-	gc->chip_types[1].chip.irq_unmask	= irq_gc_mask_set_bit,
-	gc->chip_types[1].chip.irq_set_type	= gpio_set_irq_type,
-	gc->chip_types[1].chip.irq_set_wake	= gpio_set_irq_wake,
-	gc->chip_types[1].chip.flags		= IRQCHIP_MASK_ON_SUSPEND,
+	gc->chip_types[1].chip.irq_startup	= gpio_startup_irq;
+	gc->chip_types[1].chip.irq_ack		= irq_gc_ack_clr_bit;
+	gc->chip_types[1].chip.irq_mask		= irq_gc_mask_clr_bit;
+	gc->chip_types[1].chip.irq_unmask	= irq_gc_mask_set_bit;
+	gc->chip_types[1].chip.irq_set_type	= gpio_set_irq_type;
+	gc->chip_types[1].chip.irq_set_wake	= gpio_set_irq_wake;
+	gc->chip_types[1].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
 
 	/* Setup chained handler for this GPIO bank */
 	irq_set_handler_data(bank->irq, bank);

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int
  2014-03-04 10:57             ` Thomas Gleixner
@ 2014-03-04 11:14               ` James Hogan
  0 siblings, 0 replies; 17+ messages in thread
From: James Hogan @ 2014-03-04 11:14 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Russell King - ARM Linux, grant.likely, linus.walleij,
	Jean-Jacques Hiblot, linux-kernel, linux-arm-kernel

On 04/03/14 10:57, Thomas Gleixner wrote:
> The reason is the usage of commata instead of semicolons. You can work
> around that with cocci, but that gets ugly ....
> 
> Thanks,
> 
> 	tglx
> 
> --- a/drivers/gpio/gpio-tz1090.c
> +++ b/drivers/gpio/gpio-tz1090.c
> @@ -488,26 +488,26 @@ static int tz1090_gpio_bank_probe(struct tz1090_gpio_bank_info *info)
>  	gc->chip_types[0].handler		= handle_level_irq;
>  	gc->chip_types[0].regs.ack		= REG_GPIO_IRQ_STS;
>  	gc->chip_types[0].regs.mask		= REG_GPIO_IRQ_EN;
> -	gc->chip_types[0].chip.irq_startup	= gpio_startup_irq,
> -	gc->chip_types[0].chip.irq_ack		= irq_gc_ack_clr_bit,
> -	gc->chip_types[0].chip.irq_mask		= irq_gc_mask_clr_bit,
> -	gc->chip_types[0].chip.irq_unmask	= irq_gc_mask_set_bit,
> -	gc->chip_types[0].chip.irq_set_type	= gpio_set_irq_type,
> -	gc->chip_types[0].chip.irq_set_wake	= gpio_set_irq_wake,
> -	gc->chip_types[0].chip.flags		= IRQCHIP_MASK_ON_SUSPEND,
> +	gc->chip_types[0].chip.irq_startup	= gpio_startup_irq;
> +	gc->chip_types[0].chip.irq_ack		= irq_gc_ack_clr_bit;
> +	gc->chip_types[0].chip.irq_mask		= irq_gc_mask_clr_bit;
> +	gc->chip_types[0].chip.irq_unmask	= irq_gc_mask_set_bit;
> +	gc->chip_types[0].chip.irq_set_type	= gpio_set_irq_type;
> +	gc->chip_types[0].chip.irq_set_wake	= gpio_set_irq_wake;
> +	gc->chip_types[0].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
>  
>  	/* edge chip type */
>  	gc->chip_types[1].type			= IRQ_TYPE_EDGE_BOTH;
>  	gc->chip_types[1].handler		= handle_edge_irq;
>  	gc->chip_types[1].regs.ack		= REG_GPIO_IRQ_STS;
>  	gc->chip_types[1].regs.mask		= REG_GPIO_IRQ_EN;
> -	gc->chip_types[1].chip.irq_startup	= gpio_startup_irq,
> -	gc->chip_types[1].chip.irq_ack		= irq_gc_ack_clr_bit,
> -	gc->chip_types[1].chip.irq_mask		= irq_gc_mask_clr_bit,
> -	gc->chip_types[1].chip.irq_unmask	= irq_gc_mask_set_bit,
> -	gc->chip_types[1].chip.irq_set_type	= gpio_set_irq_type,
> -	gc->chip_types[1].chip.irq_set_wake	= gpio_set_irq_wake,
> -	gc->chip_types[1].chip.flags		= IRQCHIP_MASK_ON_SUSPEND,
> +	gc->chip_types[1].chip.irq_startup	= gpio_startup_irq;
> +	gc->chip_types[1].chip.irq_ack		= irq_gc_ack_clr_bit;
> +	gc->chip_types[1].chip.irq_mask		= irq_gc_mask_clr_bit;
> +	gc->chip_types[1].chip.irq_unmask	= irq_gc_mask_set_bit;
> +	gc->chip_types[1].chip.irq_set_type	= gpio_set_irq_type;
> +	gc->chip_types[1].chip.irq_set_wake	= gpio_set_irq_wake;
> +	gc->chip_types[1].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
>  
>  	/* Setup chained handler for this GPIO bank */
>  	irq_set_handler_data(bank->irq, bank);
> 

Whoops, that was a subtle mistake from when I converted it from static
irqchips to using the generic irqchip stuff. Thanks for the patch, I'll
add a commit message and resubmit.

Cheers
James

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Consider a negative return value of irq_startup() as an error
  2014-02-26 22:15 ` Thomas Gleixner
  2014-02-27 16:03   ` Jean-Jacques Hiblot
@ 2014-03-07  2:49   ` Linus Walleij
  2014-03-08  9:15     ` Thomas Gleixner
  1 sibling, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2014-03-07  2:49 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Jean-Jacques Hiblot, Grant Likely, linux-kernel, linux-arm-kernel

On Thu, Feb 27, 2014 at 6:15 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
> On Tue, 25 Feb 2014, Jean-Jacques Hiblot wrote:
>
> The whole drviers/gpio directory is full of this gpio_lock_as_irq()
> called from the guts of irq_chip callbacks braindamage.

OK then we need to figure out where to place this call to lock
the lines as used by IRQs properly.

The whole thing came out as a result of the resolution of a
discussion about semantic dependencies in drivers/gpio, as drivers
were not handling gpio_* calls to gpiolib and irqchip stuff
orthogonally instead relying on implicit handling of call
dependencies.

Anyway, using a GPIO line as an IRQ makes some other usecases
(like setting it to output and bitbanging it as an I2C) impossible,
and the gpiolib definately needs to be aware that it is used as
an IRQ. And some usecases (like the line being an output)
are impossible so the use as IRQ need to be denied.

> The comment above gpiod_lock_as_irq() is so wrong it's not even funny
> anymore.

Sent a patch to fix this.

> The whole idiocy starts with commit d468bf9e, which tells people to
> call this from irq_startup/enable. But it fails to tell, that this is
> pointless because it wont prevent the interrupt from starting up.

The call is still useful for the gpiolib intrinsics, we would be better off
even if the error to lock the line as IRQ was just printed and then
ignored, as then atleast the error message would tell users that they
are trying to do something that is impossible. Before they had no clue
and were debugging their GPIO irqs for days...

> So 11 SoC lemmings followed and added this completely pointless
> nonsense to their drivers.

Maybe for the irq subsystem, but the gpio subsystem is very
happy about now knowing if a GPIO is used as IRQ or not.
It has implications for the (horrid) sysfs API to GPIO for example.

> Dammit, I told you folks often enough that workarounds in some
> subsystem do not actually cure a shortcoming in the core code. When
> the core code was written, the GPIO case which might actually fail was
> definitly not thought of. But that's not a reason for adding
> tasteless and useless workarounds to the GPIO subsystem.

So while it is true that the situation where the locking to IRQ
fails was not handled properly, this was not added to workaround
shortcomings in other subsystems, but rather to make gpiolib
aware that a certain line is used for IRQs so as to stop people
from shooting themselves in the foot using the gpiolib.

> Of course you encouraged people to copy that nonsense all over the
> place.

Not Jean-Jacques! I take the sole honor for that :-)

> All startup functions do the same thing:
>
>     if (gpio_lock_as_irq() < 0)
>        dev_err("BLA");
>     unmask_irq();
>
> Plus the shutdown functions having the gpio_unlock_as_irq() +
> mask_irq() sequence. Sigh.
>
> So the proper solution to the problem if we want to use irq_startup()
> is:
>
>   Change the return value of the irq_startup() callback to int and
>   fixup all existing implementations. This wants to be done with a
>   coccinelle script. If you hurry up, I might squeeze it into 3.14 as
>   there is no risk at all. Otherwise this is going to happen after the
>   3.15 merge window closes.

I think Jean-Jacques says he's onto this so great.

>   After that's done, remove all the copies of startup/shutdown
>   nonsense in drivers/gpio and force all gpio chips to call
>   gpio_set_irq_chip*() instead of irq_set_irq_chip*() and add generic
>   irq_startup/shutdown callbacks which are implemented in the gpiolib
>   core code.

We probably need to mirror irq_set_chip_and_handler() too since
most drivers use this, but I like this idea.

> There is a less intrusive alternative solution:
>
>   Mark the interrupt as GPIO based in the core and let the core call
>   conditonally the gpio_[un]lock_as_irq functions.

I think the first one is better actually.

I'll see what Jean-Jacques comes up with and take it from there unless
he's interested in taking it all the way.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Consider a negative return value of irq_startup() as an error
  2014-03-07  2:49   ` [PATCH] irq: Consider a negative return value of irq_startup() as an error Linus Walleij
@ 2014-03-08  9:15     ` Thomas Gleixner
  2014-03-12 14:49       ` Linus Walleij
  2014-03-12 15:06       ` [tip:irq/core] genirq: Provide irq_request/ release_resources chip callbacks tip-bot for Thomas Gleixner
  0 siblings, 2 replies; 17+ messages in thread
From: Thomas Gleixner @ 2014-03-08  9:15 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jean-Jacques Hiblot, Grant Likely, linux-kernel, linux-arm-kernel

On Fri, 7 Mar 2014, Linus Walleij wrote:
> I'll see what Jean-Jacques comes up with and take it from there unless
> he's interested in taking it all the way.

Thought more about it while trying to come up with a persuasive
argument for the other Linus to take the irq_startup change that late
in the cycle:

Using startup is the wrong point in __setup_irq() because we call
chip->irq_set_type() before we call chip->irq_startup(). And we want
this to be in that order to avoid spurious interrupts.

Proper solution below. That leaves the startup/unmask logic untouched
and provides separate callbacks for this kind of requirements. That
makes it also simpler to have common functions for all gpios as you
don't have to do the mask/unmask dance in startup/shutdown. So you can
simply create gpio_irq_request/release_resources() and let the drivers
add those to their callbacks.

If you agree, I put that into a separate branch based on an upstream
-rc so you can pull it into your gpiolib stuff and work from there.

Thanks,

	tglx

---------------------->
Subject: genirq: Provide irq_request/release_resources chip callbacks
From: Thomas Gleixner <tglx@linutronix.de>
Date: Sat, 08 Mar 2014 08:59:58 +0100

For certain irq types, e.g. gpios, it's necessary to request resources
before starting up the irq.

This might fail so we cannot use the irq_startup() callback because we
might call the irq_set_type() callback before that which does not make
sense when the resource is not available. Calling irq_startup() before
irq_set_type() can lead to spurious interrupts which is not desired
either.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h |    6 ++++++
 kernel/irq/manage.c |   28 +++++++++++++++++++++++++++-
 2 files changed, 33 insertions(+), 1 deletion(-)

Index: linux-2.6/include/linux/irq.h
===================================================================
--- linux-2.6.orig/include/linux/irq.h
+++ linux-2.6/include/linux/irq.h
@@ -303,6 +303,10 @@ static inline irq_hw_number_t irqd_to_hw
  * @irq_pm_shutdown:	function called from core code on shutdown once per chip
  * @irq_calc_mask:	Optional function to set irq_data.mask for special cases
  * @irq_print_chip:	optional to print special chip info in show_interrupts
+ * @irq_request_resources:	optional to request resources before calling
+ *				any other callback related to this irq
+ * @irq_release_resources:	optional to release resources acquired with
+ *				irq_request_resources
  * @flags:		chip specific flags
  */
 struct irq_chip {
@@ -336,6 +340,8 @@ struct irq_chip {
 	void		(*irq_calc_mask)(struct irq_data *data);
 
 	void		(*irq_print_chip)(struct irq_data *data, struct seq_file *p);
+	int		(*irq_request_resources)(struct irq_data *data);
+	void		(*irq_release_resources)(struct irq_data *data);
 
 	unsigned long	flags;
 };
Index: linux-2.6/kernel/irq/manage.c
===================================================================
--- linux-2.6.orig/kernel/irq/manage.c
+++ linux-2.6/kernel/irq/manage.c
@@ -897,6 +897,23 @@ static void irq_setup_forced_threading(s
 	}
 }
 
+static int irq_request_resources(struct irq_desc *desc)
+{
+	struct irq_data *d = &desc->irq_data;
+	struct irq_chip *c = d->chip;
+
+	return c->irq_request_resources ? c->irq_request_resources(d) : 0;
+}
+
+static void irq_release_resources(struct irq_desc *desc)
+{
+	struct irq_data *d = &desc->irq_data;
+	struct irq_chip *c = d->chip;
+
+	if (c->irq_release_resources)
+		c->irq_release_resources(d);
+}
+
 /*
  * Internal function to register an irqaction - typically used to
  * allocate special interrupts that are part of the architecture.
@@ -1092,6 +1109,13 @@ __setup_irq(unsigned int irq, struct irq
 	}
 
 	if (!shared) {
+		ret = irq_request_resources(desc);
+		if (ret) {
+			pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n",
+			       new->name, irq, desc->irq_data.chip->name);
+			goto out_mask;
+		}
+
 		init_waitqueue_head(&desc->wait_for_threads);
 
 		/* Setup the type (level, edge polarity) if configured: */
@@ -1262,8 +1286,10 @@ static struct irqaction *__free_irq(unsi
 	*action_ptr = action->next;
 
 	/* If this was the last handler, shut down the IRQ line: */
-	if (!desc->action)
+	if (!desc->action) {
 		irq_shutdown(desc);
+		irq_release_resources(desc);
+	}
 
 #ifdef CONFIG_SMP
 	/* make sure affinity_hint is cleaned up */






^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Consider a negative return value of irq_startup() as an error
  2014-03-08  9:15     ` Thomas Gleixner
@ 2014-03-12 14:49       ` Linus Walleij
  2014-03-12 15:10         ` Thomas Gleixner
  2014-03-12 15:06       ` [tip:irq/core] genirq: Provide irq_request/ release_resources chip callbacks tip-bot for Thomas Gleixner
  1 sibling, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2014-03-12 14:49 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Jean-Jacques Hiblot, Grant Likely, linux-kernel, linux-arm-kernel

On Sat, Mar 8, 2014 at 10:15 AM, Thomas Gleixner <tglx@linutronix.de> wrote:

> On Fri, 7 Mar 2014, Linus Walleij wrote:
>> I'll see what Jean-Jacques comes up with and take it from there unless
>> he's interested in taking it all the way.
>
> Thought more about it while trying to come up with a persuasive
> argument for the other Linus to take the irq_startup change that late
> in the cycle:
>
> Using startup is the wrong point in __setup_irq() because we call
> chip->irq_set_type() before we call chip->irq_startup(). And we want
> this to be in that order to avoid spurious interrupts.
>
> Proper solution below. That leaves the startup/unmask logic untouched
> and provides separate callbacks for this kind of requirements. That
> makes it also simpler to have common functions for all gpios as you
> don't have to do the mask/unmask dance in startup/shutdown. So you can
> simply create gpio_irq_request/release_resources() and let the drivers
> add those to their callbacks.
>
> If you agree, I put that into a separate branch based on an upstream
> -rc so you can pull it into your gpiolib stuff and work from there.

Yeah I really like the looks of this!
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

We need to think about whether the gpiolib changes are serious
enough to be pushed this late in the -rc cycle though.

The thing is that the flagging of GPIO lines as IRQs was to fix
up the ages-old mess of sequential semantic dependencies between
different unrelated gpiolib and irqchip calls, and these bugs have
been around since the first irqchip was implemented in
drivers/gpio I think :-(

But if you prefer, I'll surely do it.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [tip:irq/core] genirq: Provide irq_request/ release_resources chip callbacks
  2014-03-08  9:15     ` Thomas Gleixner
  2014-03-12 14:49       ` Linus Walleij
@ 2014-03-12 15:06       ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Thomas Gleixner @ 2014-03-12 15:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, grant.likely, hpa, mingo, jjhiblot, tglx, linus.walleij

Commit-ID:  c1bacbae8192dd2a9ebadd22d793b68054f6c6e5
Gitweb:     http://git.kernel.org/tip/c1bacbae8192dd2a9ebadd22d793b68054f6c6e5
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sat, 8 Mar 2014 08:59:58 +0100
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 12 Mar 2014 16:00:24 +0100

genirq: Provide irq_request/release_resources chip callbacks

For certain irq types, e.g. gpios, it's necessary to request resources
before starting up the irq.

This might fail so we cannot use the irq_startup() callback because we
might call the irq_set_type() callback before that which does not make
sense when the resource is not available. Calling irq_startup() before
irq_set_type() can lead to spurious interrupts which is not desired
either.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org 
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1403080857160.18573@ionos.tec.linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h |  6 ++++++
 kernel/irq/manage.c | 28 +++++++++++++++++++++++++++-
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 7dc1003..e675971 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -303,6 +303,10 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
  * @irq_pm_shutdown:	function called from core code on shutdown once per chip
  * @irq_calc_mask:	Optional function to set irq_data.mask for special cases
  * @irq_print_chip:	optional to print special chip info in show_interrupts
+ * @irq_request_resources:	optional to request resources before calling
+ *				any other callback related to this irq
+ * @irq_release_resources:	optional to release resources acquired with
+ *				irq_request_resources
  * @flags:		chip specific flags
  */
 struct irq_chip {
@@ -336,6 +340,8 @@ struct irq_chip {
 	void		(*irq_calc_mask)(struct irq_data *data);
 
 	void		(*irq_print_chip)(struct irq_data *data, struct seq_file *p);
+	int		(*irq_request_resources)(struct irq_data *data);
+	void		(*irq_release_resources)(struct irq_data *data);
 
 	unsigned long	flags;
 };
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index d3bf660..5d35cbe 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -896,6 +896,23 @@ static void irq_setup_forced_threading(struct irqaction *new)
 	}
 }
 
+static int irq_request_resources(struct irq_desc *desc)
+{
+	struct irq_data *d = &desc->irq_data;
+	struct irq_chip *c = d->chip;
+
+	return c->irq_request_resources ? c->irq_request_resources(d) : 0;
+}
+
+static void irq_release_resources(struct irq_desc *desc)
+{
+	struct irq_data *d = &desc->irq_data;
+	struct irq_chip *c = d->chip;
+
+	if (c->irq_release_resources)
+		c->irq_release_resources(d);
+}
+
 /*
  * Internal function to register an irqaction - typically used to
  * allocate special interrupts that are part of the architecture.
@@ -1091,6 +1108,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 	}
 
 	if (!shared) {
+		ret = irq_request_resources(desc);
+		if (ret) {
+			pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n",
+			       new->name, irq, desc->irq_data.chip->name);
+			goto out_mask;
+		}
+
 		init_waitqueue_head(&desc->wait_for_threads);
 
 		/* Setup the type (level, edge polarity) if configured: */
@@ -1261,8 +1285,10 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 	*action_ptr = action->next;
 
 	/* If this was the last handler, shut down the IRQ line: */
-	if (!desc->action)
+	if (!desc->action) {
 		irq_shutdown(desc);
+		irq_release_resources(desc);
+	}
 
 #ifdef CONFIG_SMP
 	/* make sure affinity_hint is cleaned up */

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Consider a negative return value of irq_startup() as an error
  2014-03-12 14:49       ` Linus Walleij
@ 2014-03-12 15:10         ` Thomas Gleixner
  2014-03-14  9:28           ` Linus Walleij
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2014-03-12 15:10 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jean-Jacques Hiblot, Grant Likely, linux-kernel, linux-arm-kernel

On Wed, 12 Mar 2014, Linus Walleij wrote:
> On Sat, Mar 8, 2014 at 10:15 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
> 
> > On Fri, 7 Mar 2014, Linus Walleij wrote:
> >> I'll see what Jean-Jacques comes up with and take it from there unless
> >> he's interested in taking it all the way.
> >
> > Thought more about it while trying to come up with a persuasive
> > argument for the other Linus to take the irq_startup change that late
> > in the cycle:
> >
> > Using startup is the wrong point in __setup_irq() because we call
> > chip->irq_set_type() before we call chip->irq_startup(). And we want
> > this to be in that order to avoid spurious interrupts.
> >
> > Proper solution below. That leaves the startup/unmask logic untouched
> > and provides separate callbacks for this kind of requirements. That
> > makes it also simpler to have common functions for all gpios as you
> > don't have to do the mask/unmask dance in startup/shutdown. So you can
> > simply create gpio_irq_request/release_resources() and let the drivers
> > add those to their callbacks.
> >
> > If you agree, I put that into a separate branch based on an upstream
> > -rc so you can pull it into your gpiolib stuff and work from there.
> 
> Yeah I really like the looks of this!
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> 
> We need to think about whether the gpiolib changes are serious
> enough to be pushed this late in the -rc cycle though.
> 
> The thing is that the flagging of GPIO lines as IRQs was to fix
> up the ages-old mess of sequential semantic dependencies between
> different unrelated gpiolib and irqchip calls, and these bugs have
> been around since the first irqchip was implemented in
> drivers/gpio I think :-(
> 
> But if you prefer, I'll surely do it.

Nah. We can just do that for 3.15. If people have the urge to backport
it, it's simple enough to do so.

I pushed out the patch to a separate branch

  git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip irq/for-gpio

and merged that branch back into irq/core.

So you can just pull irq/for-gpio into the gpio work and base the gpio
related changes on top of that. Just mention it in the pull request to
the other Linus that it contains an irq/core change which avoids merge
dependencies.

Thanks,

	tglx


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] irq: Consider a negative return value of irq_startup() as an error
  2014-03-12 15:10         ` Thomas Gleixner
@ 2014-03-14  9:28           ` Linus Walleij
  0 siblings, 0 replies; 17+ messages in thread
From: Linus Walleij @ 2014-03-14  9:28 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Jean-Jacques Hiblot, Grant Likely, linux-kernel, linux-arm-kernel

On Wed, Mar 12, 2014 at 4:10 PM, Thomas Gleixner <tglx@linutronix.de> wrote:

> I pushed out the patch to a separate branch
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip irq/for-gpio
>
> and merged that branch back into irq/core.
>
> So you can just pull irq/for-gpio into the gpio work and base the gpio
> related changes on top of that. Just mention it in the pull request to
> the other Linus that it contains an irq/core change which avoids merge
> dependencies.

OK I first merged in the v3.14-rc6 as base and then pulled this in,
so I will proceed to switch the calls over to request/release
resources.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-03-14  9:28 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-25 16:28 [PATCH] irq: Consider a negative return value of irq_startup() as an error Jean-Jacques Hiblot
2014-02-26 22:15 ` Thomas Gleixner
2014-02-27 16:03   ` Jean-Jacques Hiblot
2014-02-27 17:21     ` [PATCH] irq: Changed the return type of irq_chip.irq_startup() from unsigned int to int Jean-Jacques Hiblot
2014-02-28 22:52       ` James Hogan
2014-03-01 15:31         ` Thomas Gleixner
2014-03-01 16:01           ` Russell King - ARM Linux
2014-03-03  8:55             ` Jean-Jacques Hiblot
2014-03-04 10:57             ` Thomas Gleixner
2014-03-04 11:14               ` James Hogan
2014-03-03  9:22         ` [PATCH v2] " Jean-Jacques Hiblot
2014-03-07  2:49   ` [PATCH] irq: Consider a negative return value of irq_startup() as an error Linus Walleij
2014-03-08  9:15     ` Thomas Gleixner
2014-03-12 14:49       ` Linus Walleij
2014-03-12 15:10         ` Thomas Gleixner
2014-03-14  9:28           ` Linus Walleij
2014-03-12 15:06       ` [tip:irq/core] genirq: Provide irq_request/ release_resources chip callbacks tip-bot for Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).