diff mbox series

[1/5] gpio: Don't fiddle with irqchips marked as immutable

Message ID 20220223154405.54912-2-maz@kernel.org (mailing list archive)
State Superseded
Headers show
Series gpiolib: Handle immutable irq_chip structures | expand

Commit Message

Marc Zyngier Feb. 23, 2022, 3:44 p.m. UTC
In order to move away from gpiolib messing with the internals of
unsuspecting irqchips, add a flag by which irqchips advertise
that they are not to be messed with, and do solemnly swear that
they correctly call into the gpiolib helpers wueh required.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/gpio/gpiolib.c | 7 ++++++-
 include/linux/irq.h    | 2 ++
 kernel/irq/debugfs.c   | 1 +
 3 files changed, 9 insertions(+), 1 deletion(-)

Comments

Jeffrey Hugo Feb. 23, 2022, 5:48 p.m. UTC | #1
On Wed, Feb 23, 2022 at 10:40 AM Marc Zyngier <maz@kernel.org> wrote:
>
> In order to move away from gpiolib messing with the internals of
> unsuspecting irqchips, add a flag by which irqchips advertise
> that they are not to be messed with, and do solemnly swear that
> they correctly call into the gpiolib helpers wueh required.

"wueh"?  Should that be "when"?
Marc Zyngier Feb. 23, 2022, 6:14 p.m. UTC | #2
On 2022-02-23 17:48, Jeffrey Hugo wrote:
> On Wed, Feb 23, 2022 at 10:40 AM Marc Zyngier <maz@kernel.org> wrote:
>> 
>> In order to move away from gpiolib messing with the internals of
>> unsuspecting irqchips, add a flag by which irqchips advertise
>> that they are not to be messed with, and do solemnly swear that
>> they correctly call into the gpiolib helpers wueh required.
> 
> "wueh"?  Should that be "when"?

Absolutely. There are more typos in this cover letter, and probably
even more in the individual patches!

         M.
Thierry Reding Feb. 24, 2022, 4:51 p.m. UTC | #3
On Wed, Feb 23, 2022 at 03:44:01PM +0000, Marc Zyngier wrote:
> In order to move away from gpiolib messing with the internals of
> unsuspecting irqchips, add a flag by which irqchips advertise
> that they are not to be messed with, and do solemnly swear that
> they correctly call into the gpiolib helpers wueh required.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/gpio/gpiolib.c | 7 ++++++-
>  include/linux/irq.h    | 2 ++
>  kernel/irq/debugfs.c   | 1 +
>  3 files changed, 9 insertions(+), 1 deletion(-)

I kind of like this. The bit where the const cast is essentially guarded
by an "immutable" flag is a bit funky, but it doesn't look like there is
a good way to do it by making all references const without doing a huge
all-at-once conversion.

I've always found it a bit irritating that irq_chip was somewhere
between a container for chip-specific data and an "ops" structure. I
think it'd be even nicer if this was split into an extra struct
irq_chip_ops, which could then always be const and a struct irq_chip
that contained primarily chip-specific data as well as a pointer to
struct irq_chip_ops.

But again, this seems fairly tricky to pull off given all the
interdependencies and we can iterate on this in the future, so this
seems like a good enough compromise:

Acked-by: Thierry Reding <treding@nvidia.com>
Marc Zyngier Feb. 26, 2022, 10:32 a.m. UTC | #4
On Thu, 24 Feb 2022 16:51:41 +0000,
Thierry Reding <thierry.reding@gmail.com> wrote:
> 
> On Wed, Feb 23, 2022 at 03:44:01PM +0000, Marc Zyngier wrote:
> > In order to move away from gpiolib messing with the internals of
> > unsuspecting irqchips, add a flag by which irqchips advertise
> > that they are not to be messed with, and do solemnly swear that
> > they correctly call into the gpiolib helpers wueh required.
> > 
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  drivers/gpio/gpiolib.c | 7 ++++++-
> >  include/linux/irq.h    | 2 ++
> >  kernel/irq/debugfs.c   | 1 +
> >  3 files changed, 9 insertions(+), 1 deletion(-)
> 
> I kind of like this. The bit where the const cast is essentially guarded
> by an "immutable" flag is a bit funky, but it doesn't look like there is
> a good way to do it by making all references const without doing a huge
> all-at-once conversion.

Exactly. Somehow, we need to advertise it to the gpiolib code, and
this does the job. I hope to be able to simply drop it once everthing
is converted. One day.

> I've always found it a bit irritating that irq_chip was somewhere
> between a container for chip-specific data and an "ops" structure. I
> think it'd be even nicer if this was split into an extra struct
> irq_chip_ops, which could then always be const and a struct irq_chip
> that contained primarily chip-specific data as well as a pointer to
> struct irq_chip_ops.

But that's the thing: it almost is a pure 'ops' structure. Only two
things are getting in the way of it:

- the 'parent_dev' field: this is now sorted, as I moved it to the
  irq_domain structure, and updated all the relevant drivers (see what
  is currently in -next).

- the .name field: it really should never be something that changes
  from one instance of the chip to another. Which is why we have the
  .irq_print_chip() method to handle that (and ideally we'd stick to
  pure const names). I'm addressing this as I go, but everything in
  drivers/irqchip/ should be fixed in -next.

The "context" part really lives in irq_domain.

> But again, this seems fairly tricky to pull off given all the
> interdependencies and we can iterate on this in the future, so this
> seems like a good enough compromise:
> 
> Acked-by: Thierry Reding <treding@nvidia.com>

Thanks,

	M.
diff mbox series

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 3859911b61e9..515838708b00 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1475,6 +1475,11 @@  static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
 {
 	struct irq_chip *irqchip = gc->irq.chip;
 
+	if (irqchip->flags & IRQCHIP_IMMUTABLE) {
+		chip_info(gc, "Immutable chip, not updating\n");
+		return;
+	}
+
 	if (!irqchip->irq_request_resources &&
 	    !irqchip->irq_release_resources) {
 		irqchip->irq_request_resources = gpiochip_irq_reqres;
@@ -1633,7 +1638,7 @@  static void gpiochip_irqchip_remove(struct gpio_chip *gc)
 		irq_domain_remove(gc->irq.domain);
 	}
 
-	if (irqchip) {
+	if (irqchip && !(irqchip->flags & IRQCHIP_IMMUTABLE)) {
 		if (irqchip->irq_request_resources == gpiochip_irq_reqres) {
 			irqchip->irq_request_resources = NULL;
 			irqchip->irq_release_resources = NULL;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index f92788ccdba2..505308253d23 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -569,6 +569,7 @@  struct irq_chip {
  * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND:  Invokes __enable_irq()/__disable_irq() for wake irqs
  *                                    in the suspend path if they are in disabled state
  * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
+ * IRQCHIP_IMMUTABLE:		      Don't ever change anything in this chip
  */
 enum {
 	IRQCHIP_SET_TYPE_MASKED			= (1 <<  0),
@@ -582,6 +583,7 @@  enum {
 	IRQCHIP_SUPPORTS_NMI			= (1 <<  8),
 	IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND	= (1 <<  9),
 	IRQCHIP_AFFINITY_PRE_STARTUP		= (1 << 10),
+	IRQCHIP_IMMUTABLE			= (1 << 11),
 };
 
 #include <linux/irqdesc.h>
diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c
index 2b43f5f5033d..bc8e40cf2b65 100644
--- a/kernel/irq/debugfs.c
+++ b/kernel/irq/debugfs.c
@@ -58,6 +58,7 @@  static const struct irq_bit_descr irqchip_flags[] = {
 	BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI),
 	BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI),
 	BIT_MASK_DESCR(IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND),
+	BIT_MASK_DESCR(IRQCHIP_IMMUTABLE),
 };
 
 static void