diff mbox series

gpio: sifive: Make the irqchip immutable

Message ID 73c75a67d1c87b049d633057c0e765e708ee02a2.1652884788.git.geert+renesas@glider.be
State Superseded
Headers show
Series gpio: sifive: Make the irqchip immutable | expand

Commit Message

Geert Uytterhoeven May 18, 2022, 2:40 p.m. UTC
Commit 6c846d026d49 ("gpio: Don't fiddle with irqchips marked as
immutable") added a warning to indicate if the gpiolib is altering the
internals of irqchips.  Following this change the following warning is
now observed for the sifive driver:

    gpio gpiochip1: (38001000.gpio-controller): not an immutable chip, please consider fixing it!

Fix this by making the irqchip in the sifive driver immutable.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Against linux-next.
Boot-tested on SiPEED MAiXBiT (Canaan K210).
---
 drivers/gpio/gpio-sifive.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Comments

kernel test robot May 20, 2022, 3:28 a.m. UTC | #1
Hi Geert,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on linusw-gpio/for-next v5.18-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Geert-Uytterhoeven/gpio-sifive-Make-the-irqchip-immutable/20220518-224530
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 210e04ff768142b96452030c4c2627512b30ad95
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20220520/202205201122.xuM6bWUt-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/3db66356e9f7309998a9172feeb84d8b226ad539
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Geert-Uytterhoeven/gpio-sifive-Make-the-irqchip-immutable/20220518-224530
        git checkout 3db66356e9f7309998a9172feeb84d8b226ad539
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/gpio/gpio-sifive.c:151:27: error: 'IRQCHIP_IMMUTABLE' undeclared here (not in a function); did you mean 'IS_IMMUTABLE'?
     151 |         .flags          = IRQCHIP_IMMUTABLE,
         |                           ^~~~~~~~~~~~~~~~~
         |                           IS_IMMUTABLE
>> drivers/gpio/gpio-sifive.c:152:9: error: 'GPIOCHIP_IRQ_RESOURCE_HELPERS' undeclared here (not in a function)
     152 |         GPIOCHIP_IRQ_RESOURCE_HELPERS,
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpio/gpio-sifive.c:152:9: warning: excess elements in struct initializer
   drivers/gpio/gpio-sifive.c:152:9: note: (near initialization for 'sifive_gpio_irqchip')
   drivers/gpio/gpio-sifive.c: In function 'sifive_gpio_probe':
>> drivers/gpio/gpio-sifive.c:249:9: error: implicit declaration of function 'gpio_irq_chip_set_chip' [-Werror=implicit-function-declaration]
     249 |         gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip);
         |         ^~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +151 drivers/gpio/gpio-sifive.c

   141	
   142	static const struct irq_chip sifive_gpio_irqchip = {
   143		.name		= "sifive-gpio",
   144		.irq_set_type	= sifive_gpio_irq_set_type,
   145		.irq_mask	= irq_chip_mask_parent,
   146		.irq_unmask	= irq_chip_unmask_parent,
   147		.irq_enable	= sifive_gpio_irq_enable,
   148		.irq_disable	= sifive_gpio_irq_disable,
   149		.irq_eoi	= sifive_gpio_irq_eoi,
   150		.irq_set_affinity = sifive_gpio_irq_set_affinity,
 > 151		.flags		= IRQCHIP_IMMUTABLE,
 > 152		GPIOCHIP_IRQ_RESOURCE_HELPERS,
   153	};
   154	
   155	static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
   156						     unsigned int child,
   157						     unsigned int child_type,
   158						     unsigned int *parent,
   159						     unsigned int *parent_type)
   160	{
   161		struct sifive_gpio *chip = gpiochip_get_data(gc);
   162		struct irq_data *d = irq_get_irq_data(chip->irq_number[child]);
   163	
   164		*parent_type = IRQ_TYPE_NONE;
   165		*parent = irqd_to_hwirq(d);
   166	
   167		return 0;
   168	}
   169	
   170	static const struct regmap_config sifive_gpio_regmap_config = {
   171		.reg_bits = 32,
   172		.reg_stride = 4,
   173		.val_bits = 32,
   174		.fast_io = true,
   175		.disable_locking = true,
   176	};
   177	
   178	static int sifive_gpio_probe(struct platform_device *pdev)
   179	{
   180		struct device *dev = &pdev->dev;
   181		struct device_node *node = pdev->dev.of_node;
   182		struct device_node *irq_parent;
   183		struct irq_domain *parent;
   184		struct gpio_irq_chip *girq;
   185		struct sifive_gpio *chip;
   186		int ret, ngpio, i;
   187	
   188		chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
   189		if (!chip)
   190			return -ENOMEM;
   191	
   192		chip->base = devm_platform_ioremap_resource(pdev, 0);
   193		if (IS_ERR(chip->base)) {
   194			dev_err(dev, "failed to allocate device memory\n");
   195			return PTR_ERR(chip->base);
   196		}
   197	
   198		chip->regs = devm_regmap_init_mmio(dev, chip->base,
   199						   &sifive_gpio_regmap_config);
   200		if (IS_ERR(chip->regs))
   201			return PTR_ERR(chip->regs);
   202	
   203		ngpio = of_irq_count(node);
   204		if (ngpio > SIFIVE_GPIO_MAX) {
   205			dev_err(dev, "Too many GPIO interrupts (max=%d)\n",
   206				SIFIVE_GPIO_MAX);
   207			return -ENXIO;
   208		}
   209	
   210		irq_parent = of_irq_find_parent(node);
   211		if (!irq_parent) {
   212			dev_err(dev, "no IRQ parent node\n");
   213			return -ENODEV;
   214		}
   215		parent = irq_find_host(irq_parent);
   216		if (!parent) {
   217			dev_err(dev, "no IRQ parent domain\n");
   218			return -ENODEV;
   219		}
   220	
   221		for (i = 0; i < ngpio; i++)
   222			chip->irq_number[i] = platform_get_irq(pdev, i);
   223	
   224		ret = bgpio_init(&chip->gc, dev, 4,
   225				 chip->base + SIFIVE_GPIO_INPUT_VAL,
   226				 chip->base + SIFIVE_GPIO_OUTPUT_VAL,
   227				 NULL,
   228				 chip->base + SIFIVE_GPIO_OUTPUT_EN,
   229				 chip->base + SIFIVE_GPIO_INPUT_EN,
   230				 BGPIOF_READ_OUTPUT_REG_SET);
   231		if (ret) {
   232			dev_err(dev, "unable to init generic GPIO\n");
   233			return ret;
   234		}
   235	
   236		/* Disable all GPIO interrupts before enabling parent interrupts */
   237		regmap_write(chip->regs, SIFIVE_GPIO_RISE_IE, 0);
   238		regmap_write(chip->regs, SIFIVE_GPIO_FALL_IE, 0);
   239		regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IE, 0);
   240		regmap_write(chip->regs, SIFIVE_GPIO_LOW_IE, 0);
   241		chip->irq_state = 0;
   242	
   243		chip->gc.base = -1;
   244		chip->gc.ngpio = ngpio;
   245		chip->gc.label = dev_name(dev);
   246		chip->gc.parent = dev;
   247		chip->gc.owner = THIS_MODULE;
   248		girq = &chip->gc.irq;
 > 249		gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip);
   250		girq->fwnode = of_node_to_fwnode(node);
   251		girq->parent_domain = parent;
   252		girq->child_to_parent_hwirq = sifive_gpio_child_to_parent_hwirq;
   253		girq->handler = handle_bad_irq;
   254		girq->default_type = IRQ_TYPE_NONE;
   255	
   256		platform_set_drvdata(pdev, chip);
   257		return gpiochip_add_data(&chip->gc, chip);
   258	}
   259
Geert Uytterhoeven May 20, 2022, 6:46 a.m. UTC | #2
Hi Kernel Test Robot,

On Fri, May 20, 2022 at 5:29 AM kernel test robot <lkp@intel.com> wrote:
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on linusw-gpio/for-next v5.18-rc7]

As of commit 2d3535ed2c73fee3 ("MAINTAINERS: update the GPIO git tree
entry"), the GPIO for-next tree has changed to
git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#gpio/for-next

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
diff mbox series

Patch

diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
index 03b8c4de2e91e3c4..a48f62780e099040 100644
--- a/drivers/gpio/gpio-sifive.c
+++ b/drivers/gpio/gpio-sifive.c
@@ -79,6 +79,7 @@  static void sifive_gpio_irq_enable(struct irq_data *d)
 	u32 bit = BIT(offset);
 	unsigned long flags;
 
+	gpiochip_enable_irq(gc, d->hwirq);
 	irq_chip_enable_parent(d);
 
 	/* Switch to input */
@@ -106,6 +107,7 @@  static void sifive_gpio_irq_disable(struct irq_data *d)
 	assign_bit(offset, &chip->irq_state, 0);
 	sifive_gpio_set_ie(chip, offset);
 	irq_chip_disable_parent(d);
+	gpiochip_disable_irq(gc, d->hwirq);
 }
 
 static void sifive_gpio_irq_eoi(struct irq_data *d)
@@ -137,7 +139,7 @@  static int sifive_gpio_irq_set_affinity(struct irq_data *data,
 	return -EINVAL;
 }
 
-static struct irq_chip sifive_gpio_irqchip = {
+static const struct irq_chip sifive_gpio_irqchip = {
 	.name		= "sifive-gpio",
 	.irq_set_type	= sifive_gpio_irq_set_type,
 	.irq_mask	= irq_chip_mask_parent,
@@ -146,6 +148,8 @@  static struct irq_chip sifive_gpio_irqchip = {
 	.irq_disable	= sifive_gpio_irq_disable,
 	.irq_eoi	= sifive_gpio_irq_eoi,
 	.irq_set_affinity = sifive_gpio_irq_set_affinity,
+	.flags		= IRQCHIP_IMMUTABLE,
+	GPIOCHIP_IRQ_RESOURCE_HELPERS,
 };
 
 static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
@@ -242,7 +246,7 @@  static int sifive_gpio_probe(struct platform_device *pdev)
 	chip->gc.parent = dev;
 	chip->gc.owner = THIS_MODULE;
 	girq = &chip->gc.irq;
-	girq->chip = &sifive_gpio_irqchip;
+	gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip);
 	girq->fwnode = of_node_to_fwnode(node);
 	girq->parent_domain = parent;
 	girq->child_to_parent_hwirq = sifive_gpio_child_to_parent_hwirq;