linux-sg2042/drivers/gpio/gpio-dwapb.c

849 lines
21 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-only
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
/*
* Copyright (c) 2011 Jamie Iles
*
* All enquiries to support@picochip.com
*/
#include <linux/acpi.h>
#include <linux/clk.h>
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#include <linux/err.h>
#include <linux/gpio/driver.h>
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/mod_devicetable.h>
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#include "gpiolib.h"
#include "gpiolib-acpi.h"
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#define GPIO_SWPORTA_DR 0x00
#define GPIO_SWPORTA_DDR 0x04
#define GPIO_SWPORTB_DR 0x0c
#define GPIO_SWPORTB_DDR 0x10
#define GPIO_SWPORTC_DR 0x18
#define GPIO_SWPORTC_DDR 0x1c
#define GPIO_SWPORTD_DR 0x24
#define GPIO_SWPORTD_DDR 0x28
#define GPIO_INTEN 0x30
#define GPIO_INTMASK 0x34
#define GPIO_INTTYPE_LEVEL 0x38
#define GPIO_INT_POLARITY 0x3c
#define GPIO_INTSTATUS 0x40
#define GPIO_PORTA_DEBOUNCE 0x48
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#define GPIO_PORTA_EOI 0x4c
#define GPIO_EXT_PORTA 0x50
#define GPIO_EXT_PORTB 0x54
#define GPIO_EXT_PORTC 0x58
#define GPIO_EXT_PORTD 0x5c
#define DWAPB_DRIVER_NAME "gpio-dwapb"
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#define DWAPB_MAX_PORTS 4
#define DWAPB_MAX_GPIOS 32
#define GPIO_EXT_PORT_STRIDE 0x04 /* register stride 32 bits */
#define GPIO_SWPORT_DR_STRIDE 0x0c /* register stride 3*32 bits */
#define GPIO_SWPORT_DDR_STRIDE 0x0c /* register stride 3*32 bits */
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
#define GPIO_REG_OFFSET_V1 0
#define GPIO_REG_OFFSET_V2 1
#define GPIO_REG_OFFSET_MASK BIT(0)
#define GPIO_INTMASK_V2 0x44
#define GPIO_INTTYPE_LEVEL_V2 0x34
#define GPIO_INT_POLARITY_V2 0x38
#define GPIO_INTSTATUS_V2 0x3c
#define GPIO_PORTA_EOI_V2 0x40
#define DWAPB_NR_CLOCKS 2
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
struct dwapb_gpio;
struct dwapb_port_property {
struct fwnode_handle *fwnode;
unsigned int idx;
unsigned int ngpio;
unsigned int gpio_base;
int irq[DWAPB_MAX_GPIOS];
};
struct dwapb_platform_data {
struct dwapb_port_property *properties;
unsigned int nports;
};
#ifdef CONFIG_PM_SLEEP
/* Store GPIO context across system-wide suspend/resume transitions */
struct dwapb_context {
u32 data;
u32 dir;
u32 ext;
u32 int_en;
u32 int_mask;
u32 int_type;
u32 int_pol;
u32 int_deb;
u32 wake_en;
};
#endif
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct dwapb_gpio_port_irqchip {
unsigned int nr_irqs;
unsigned int irq[DWAPB_MAX_GPIOS];
};
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
struct dwapb_gpio_port {
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
struct gpio_chip gc;
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct dwapb_gpio_port_irqchip *pirq;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
struct dwapb_gpio *gpio;
#ifdef CONFIG_PM_SLEEP
struct dwapb_context *ctx;
#endif
unsigned int idx;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
};
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
#define to_dwapb_gpio(_gc) \
(container_of(_gc, struct dwapb_gpio_port, gc)->gpio)
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
struct dwapb_gpio {
struct device *dev;
void __iomem *regs;
struct dwapb_gpio_port *ports;
unsigned int nr_ports;
unsigned int flags;
struct reset_control *rst;
struct clk_bulk_data clks[DWAPB_NR_CLOCKS];
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
};
static inline u32 gpio_reg_v2_convert(unsigned int offset)
{
switch (offset) {
case GPIO_INTMASK:
return GPIO_INTMASK_V2;
case GPIO_INTTYPE_LEVEL:
return GPIO_INTTYPE_LEVEL_V2;
case GPIO_INT_POLARITY:
return GPIO_INT_POLARITY_V2;
case GPIO_INTSTATUS:
return GPIO_INTSTATUS_V2;
case GPIO_PORTA_EOI:
return GPIO_PORTA_EOI_V2;
}
return offset;
}
static inline u32 gpio_reg_convert(struct dwapb_gpio *gpio, unsigned int offset)
{
if ((gpio->flags & GPIO_REG_OFFSET_MASK) == GPIO_REG_OFFSET_V2)
return gpio_reg_v2_convert(offset);
return offset;
}
static inline u32 dwapb_read(struct dwapb_gpio *gpio, unsigned int offset)
{
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
struct gpio_chip *gc = &gpio->ports[0].gc;
void __iomem *reg_base = gpio->regs;
return gc->read_reg(reg_base + gpio_reg_convert(gpio, offset));
}
static inline void dwapb_write(struct dwapb_gpio *gpio, unsigned int offset,
u32 val)
{
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
struct gpio_chip *gc = &gpio->ports[0].gc;
void __iomem *reg_base = gpio->regs;
gc->write_reg(reg_base + gpio_reg_convert(gpio, offset), val);
}
static struct dwapb_gpio_port *dwapb_offs_to_port(struct dwapb_gpio *gpio, unsigned int offs)
{
struct dwapb_gpio_port *port;
int i;
for (i = 0; i < gpio->nr_ports; i++) {
port = &gpio->ports[i];
if (port->idx == offs / DWAPB_MAX_GPIOS)
return port;
}
return NULL;
}
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
{
struct dwapb_gpio_port *port = dwapb_offs_to_port(gpio, offs);
struct gpio_chip *gc;
u32 pol;
int val;
if (!port)
return;
gc = &port->gc;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
pol = dwapb_read(gpio, GPIO_INT_POLARITY);
/* Just read the current value right out of the data register */
val = gc->get(gc, offs % DWAPB_MAX_GPIOS);
if (val)
pol &= ~BIT(offs);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
else
pol |= BIT(offs);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
dwapb_write(gpio, GPIO_INT_POLARITY, pol);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
static u32 dwapb_do_irq(struct dwapb_gpio *gpio)
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
{
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct gpio_chip *gc = &gpio->ports[0].gc;
unsigned long irq_status;
irq_hw_number_t hwirq;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
irq_status = dwapb_read(gpio, GPIO_INTSTATUS);
for_each_set_bit(hwirq, &irq_status, DWAPB_MAX_GPIOS) {
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
int gpio_irq = irq_find_mapping(gc->irq.domain, hwirq);
u32 irq_type = irq_get_trigger_type(gpio_irq);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
generic_handle_irq(gpio_irq);
if ((irq_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
dwapb_toggle_trigger(gpio, hwirq);
}
return irq_status;
}
static void dwapb_irq_handler(struct irq_desc *desc)
{
struct dwapb_gpio *gpio = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
chained_irq_enter(chip, desc);
dwapb_do_irq(gpio);
chained_irq_exit(chip, desc);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id)
{
return IRQ_RETVAL(dwapb_do_irq(dev_id));
}
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
static void dwapb_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
u32 val = BIT(irqd_to_hwirq(d));
unsigned long flags;
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
dwapb_write(gpio, GPIO_PORTA_EOI, val);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
}
static void dwapb_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
unsigned long flags;
u32 val;
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTMASK) | BIT(hwirq);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
dwapb_write(gpio, GPIO_INTMASK, val);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
gpiochip_disable_irq(gc, hwirq);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
}
static void dwapb_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
unsigned long flags;
u32 val;
gpiochip_enable_irq(gc, hwirq);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(hwirq);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
dwapb_write(gpio, GPIO_INTMASK, val);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
}
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
static void dwapb_irq_enable(struct irq_data *d)
{
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
unsigned long flags;
u32 val;
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTEN);
val |= BIT(irqd_to_hwirq(d));
dwapb_write(gpio, GPIO_INTEN, val);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
static void dwapb_irq_disable(struct irq_data *d)
{
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
unsigned long flags;
u32 val;
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTEN);
val &= ~BIT(irqd_to_hwirq(d));
dwapb_write(gpio, GPIO_INTEN, val);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
static int dwapb_irq_set_type(struct irq_data *d, u32 type)
{
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
irq_hw_number_t bit = irqd_to_hwirq(d);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
unsigned long level, polarity, flags;
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);
polarity = dwapb_read(gpio, GPIO_INT_POLARITY);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
level |= BIT(bit);
dwapb_toggle_trigger(gpio, bit);
break;
case IRQ_TYPE_EDGE_RISING:
level |= BIT(bit);
polarity |= BIT(bit);
break;
case IRQ_TYPE_EDGE_FALLING:
level |= BIT(bit);
polarity &= ~BIT(bit);
break;
case IRQ_TYPE_LEVEL_HIGH:
level &= ~BIT(bit);
polarity |= BIT(bit);
break;
case IRQ_TYPE_LEVEL_LOW:
level &= ~BIT(bit);
polarity &= ~BIT(bit);
break;
}
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_handler_locked(d, handle_level_irq);
else if (type & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(d, handle_edge_irq);
dwapb_write(gpio, GPIO_INTTYPE_LEVEL, level);
if (type != IRQ_TYPE_EDGE_BOTH)
dwapb_write(gpio, GPIO_INT_POLARITY, polarity);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
struct dwapb_context *ctx = gpio->ports[0].ctx;
irq_hw_number_t bit = irqd_to_hwirq(d);
if (enable)
ctx->wake_en |= BIT(bit);
else
ctx->wake_en &= ~BIT(bit);
return 0;
}
#else
#define dwapb_irq_set_wake NULL
#endif
static const struct irq_chip dwapb_irq_chip = {
.name = DWAPB_DRIVER_NAME,
.irq_ack = dwapb_irq_ack,
.irq_mask = dwapb_irq_mask,
.irq_unmask = dwapb_irq_unmask,
.irq_set_type = dwapb_irq_set_type,
.irq_enable = dwapb_irq_enable,
.irq_disable = dwapb_irq_disable,
.irq_set_wake = dwapb_irq_set_wake,
.flags = IRQCHIP_IMMUTABLE,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
unsigned offset, unsigned debounce)
{
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
struct dwapb_gpio_port *port = gpiochip_get_data(gc);
struct dwapb_gpio *gpio = port->gpio;
unsigned long flags, val_deb;
unsigned long mask = BIT(offset);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
if (debounce)
val_deb |= mask;
else
val_deb &= ~mask;
dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb);
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
static int dwapb_gpio_set_config(struct gpio_chip *gc, unsigned offset,
unsigned long config)
{
u32 debounce;
if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
return -ENOTSUPP;
debounce = pinconf_to_config_argument(config);
return dwapb_gpio_set_debounce(gc, offset, debounce);
}
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
static int dwapb_convert_irqs(struct dwapb_gpio_port_irqchip *pirq,
struct dwapb_port_property *pp)
{
int i;
/* Group all available IRQs into an array of parental IRQs. */
for (i = 0; i < pp->ngpio; ++i) {
if (!pp->irq[i])
continue;
pirq->irq[pirq->nr_irqs++] = pp->irq[i];
}
return pirq->nr_irqs ? 0 : -ENOENT;
}
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
struct dwapb_gpio_port *port,
struct dwapb_port_property *pp)
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
{
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct dwapb_gpio_port_irqchip *pirq;
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
struct gpio_chip *gc = &port->gc;
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
struct gpio_irq_chip *girq;
int err;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
pirq = devm_kzalloc(gpio->dev, sizeof(*pirq), GFP_KERNEL);
if (!pirq)
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
return;
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
if (dwapb_convert_irqs(pirq, pp)) {
dev_warn(gpio->dev, "no IRQ for port%d\n", pp->idx);
goto err_kfree_pirq;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
girq = &gc->irq;
girq->handler = handle_bad_irq;
girq->default_type = IRQ_TYPE_NONE;
port->pirq = pirq;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
/*
* Intel ACPI-based platforms mostly have the DesignWare APB GPIO
* IRQ lane shared between several devices. In that case the parental
* IRQ has to be handled in the shared way so to be properly delivered
* to all the connected devices.
*/
if (has_acpi_companion(gpio->dev)) {
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
girq->num_parents = 0;
girq->parents = NULL;
girq->parent_handler = NULL;
err = devm_request_irq(gpio->dev, pp->irq[0],
dwapb_irq_handler_mfd,
IRQF_SHARED, DWAPB_DRIVER_NAME, gpio);
if (err) {
dev_err(gpio->dev, "error requesting IRQ\n");
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
goto err_kfree_pirq;
}
} else {
girq->num_parents = pirq->nr_irqs;
girq->parents = pirq->irq;
girq->parent_handler_data = gpio;
girq->parent_handler = dwapb_irq_handler;
}
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
gpio_irq_chip_set_chip(girq, &dwapb_irq_chip);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
return;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip GPIO-lib provides a ready-to-use interface to initialize an IRQ-chip on top of a GPIO chip. It's better from maintainability and readability point of view to use one instead of supporting a hand-written Generic IRQ-chip-based implementation. Moreover the new implementation won't cause much functional overhead but will provide a cleaner driver code. All of that makes the DW APB GPIO driver conversion pretty much justified especially seeing a tendency of the other GPIO drivers getting converted too. Here is what we do in the framework of this commit to convert the driver to using the GPIO-lib-based IRQ-chip interface: 1) IRQ ack, mask and unmask callbacks are locally defined instead of using the Generic IRQ-chip ones. 2) An irq_chip structure instance is embedded into the dwapb_gpio private data. Note we can't have a static instance of that structure since GPIO-lib will add some hooks into it by calling gpiochip_set_irq_hooks(). A warning about that would have been printed by the GPIO-lib code if we used a single irq_chip structure instance for multiple DW APB GPIO controllers. 3) Initialize the gpio_irq_chip structure embedded into the gpio_chip descriptor. By default there is no IRQ enabled so any event raised will be handled by the handle_bad_irq() IRQ flow handler. If DW APB GPIO IP-core is synthesized to have non-shared reference IRQ-lines, then as before the hierarchical and cascaded cases are distinguished by checking how many parental IRQs are defined. (Note irq_set_chained_handler_and_data() won't initialize IRQs, which descriptors couldn't be found.) If DW APB GPIO IP is used on a platform with shared IRQ line, then we simply won't let the GPIO-lib to initialize the parental IRQs, but will handle them locally in the driver. 4) Discard linear IRQ-domain and Generic IRQ-chip initialization, since GPIO-lib IRQ-chip interface will create a new domain and accept a standard IRQ-chip structure pointer based on the setting we provided in the gpio_irq_chip structure. 5) Manually select a proper IRQ flow handler directly in the irq_set_type() callback by calling irq_set_handler_locked() method, since an ordinary (not Generic) irq_chip descriptor is now utilized. Note this shalln't give any regression 6) Alter CONFIG_GPIO_DWAPB kernel config to select CONFIG_GPIOLIB_IRQCHIP instead of CONFIG_GENERIC_IRQ_CHIP. Note neither 4) nor 5) shall cause a regression of commit 6a2f4b7dadd5 ("gpio: dwapb: use a second irq chip"), since the later isn't properly used here anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:28:02 +08:00
err_kfree_pirq:
devm_kfree(gpio->dev, pirq);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
struct dwapb_port_property *pp,
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
unsigned int offs)
{
struct dwapb_gpio_port *port;
void __iomem *dat, *set, *dirout;
int err;
port = &gpio->ports[offs];
port->gpio = gpio;
port->idx = pp->idx;
#ifdef CONFIG_PM_SLEEP
port->ctx = devm_kzalloc(gpio->dev, sizeof(*port->ctx), GFP_KERNEL);
if (!port->ctx)
return -ENOMEM;
#endif
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
dat = gpio->regs + GPIO_EXT_PORTA + pp->idx * GPIO_EXT_PORT_STRIDE;
set = gpio->regs + GPIO_SWPORTA_DR + pp->idx * GPIO_SWPORT_DR_STRIDE;
dirout = gpio->regs + GPIO_SWPORTA_DDR + pp->idx * GPIO_SWPORT_DDR_STRIDE;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
/* This registers 32 GPIO lines per port */
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
err = bgpio_init(&port->gc, gpio->dev, 4, dat, set, NULL, dirout,
NULL, 0);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
if (err) {
dev_err(gpio->dev, "failed to init gpio chip for port%d\n",
port->idx);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
return err;
}
port->gc.fwnode = pp->fwnode;
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
port->gc.ngpio = pp->ngpio;
port->gc.base = pp->gpio_base;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
/* Only port A support debounce */
if (pp->idx == 0)
port->gc.set_config = dwapb_gpio_set_config;
/* Only port A can provide interrupts in all configurations of the IP */
if (pp->idx == 0)
dwapb_configure_irqs(gpio, port, pp);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
err = devm_gpiochip_add_data(gpio->dev, &port->gc, port);
if (err) {
dev_err(gpio->dev, "failed to register gpiochip for port%d\n",
port->idx);
return err;
}
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
return 0;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
static void dwapb_get_irq(struct device *dev, struct fwnode_handle *fwnode,
struct dwapb_port_property *pp)
{
int irq, j;
for (j = 0; j < pp->ngpio; j++) {
if (has_acpi_companion(dev))
irq = platform_get_irq_optional(to_platform_device(dev), j);
else
irq = fwnode_irq_get(fwnode, j);
if (irq > 0)
pp->irq[j] = irq;
}
}
static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev)
{
struct fwnode_handle *fwnode;
struct dwapb_platform_data *pdata;
struct dwapb_port_property *pp;
int nports;
int i;
nports = device_get_child_node_count(dev);
if (nports == 0)
return ERR_PTR(-ENODEV);
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return ERR_PTR(-ENOMEM);
pdata->properties = devm_kcalloc(dev, nports, sizeof(*pp), GFP_KERNEL);
if (!pdata->properties)
return ERR_PTR(-ENOMEM);
pdata->nports = nports;
i = 0;
device_for_each_child_node(dev, fwnode) {
pp = &pdata->properties[i++];
pp->fwnode = fwnode;
if (fwnode_property_read_u32(fwnode, "reg", &pp->idx) ||
pp->idx >= DWAPB_MAX_PORTS) {
dev_err(dev,
"missing/invalid port index for port%d\n", i);
fwnode_handle_put(fwnode);
return ERR_PTR(-EINVAL);
}
gpio: dwapb: Add ngpios DT-property support Indeed generic GPIO DT-schema implies that number of GPIOs should be described by the "ngpios" property located under a GPIO-provider DT node. In that case it's redundant to have a vendor-specific "snps,nr-gpios" property describing the same setting. Moreover it might be errors prone. Since commit 93d2e4322aa7 ("of: platform: Batch fwnode parsing when adding all top level devices") the fwnode parsing is resumed after the vast majority of the platform devices are added. Implicitly that commit activates re-parsing of the whole device tree GPIOs-phandle properties detected having "-gpio/-gpios" suffixes. Since the vendor-specific number of GPIOs property is defined with "-gpios" suffix, then of_link_property() will consider it as a suffix-property with "#gpio-cells" structure, which obviously it doesn't have. As a result for two DW APB GPIO controllers we'll have the next errors printed. OF: /bus@1f059000/gpio@1f044000/gpio-port@0: could not find phandle OF: /bus@1f059000/gpio@1f045000/gpio-port@0: could not get #gpio-cells for /opp-table OF: /bus@1f059000/gpio@1f044000/gpio-port@0: could not find phandle OF: /bus@1f059000/gpio@1f045000/gpio-port@0: could not get #gpio-cells for /opp-table See, the kernel fwnode parsing procedure even tried to resolve the phandle ID, which it thought was the opp-table DT-node, while in fact it was just a number "32". What would happen if that magic number actually referred to a GPIO DT-node with "#gpio-cells" property defined?.. In order to fix the problem let's mark the "snps,nr-gpios" property as deprecated and add the generic "ngpios" property support with the same purpose as the deprecated one. That and the errors log above shall motivate the platform developer to convert the DW APB GPIO DT-nodes to using the standard number of GPIOs property. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-07-30 23:27:59 +08:00
if (fwnode_property_read_u32(fwnode, "ngpios", &pp->ngpio) &&
fwnode_property_read_u32(fwnode, "snps,nr-gpios", &pp->ngpio)) {
dev_info(dev,
"failed to get number of gpios for port%d\n",
i);
pp->ngpio = DWAPB_MAX_GPIOS;
}
pp->gpio_base = -1;
/* For internal use only, new platforms mustn't exercise this */
if (is_software_node(fwnode))
fwnode_property_read_u32(fwnode, "gpio-base", &pp->gpio_base);
/*
* Only port A can provide interrupts in all configurations of
* the IP.
*/
if (pp->idx == 0)
dwapb_get_irq(dev, fwnode, pp);
}
return pdata;
}
static void dwapb_assert_reset(void *data)
{
struct dwapb_gpio *gpio = data;
reset_control_assert(gpio->rst);
}
static int dwapb_get_reset(struct dwapb_gpio *gpio)
{
int err;
gpio->rst = devm_reset_control_get_optional_shared(gpio->dev, NULL);
if (IS_ERR(gpio->rst))
return dev_err_probe(gpio->dev, PTR_ERR(gpio->rst),
"Cannot get reset descriptor\n");
err = reset_control_deassert(gpio->rst);
if (err) {
dev_err(gpio->dev, "Cannot deassert reset lane\n");
return err;
}
return devm_add_action_or_reset(gpio->dev, dwapb_assert_reset, gpio);
}
static void dwapb_disable_clks(void *data)
{
struct dwapb_gpio *gpio = data;
clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
}
static int dwapb_get_clks(struct dwapb_gpio *gpio)
{
int err;
/* Optional bus and debounce clocks */
gpio->clks[0].id = "bus";
gpio->clks[1].id = "db";
err = devm_clk_bulk_get_optional(gpio->dev, DWAPB_NR_CLOCKS,
gpio->clks);
if (err)
return dev_err_probe(gpio->dev, err,
"Cannot get APB/Debounce clocks\n");
err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks);
if (err) {
dev_err(gpio->dev, "Cannot enable APB/Debounce clocks\n");
return err;
}
return devm_add_action_or_reset(gpio->dev, dwapb_disable_clks, gpio);
}
static const struct of_device_id dwapb_of_match[] = {
{ .compatible = "snps,dw-apb-gpio", .data = (void *)GPIO_REG_OFFSET_V1},
{ .compatible = "apm,xgene-gpio-v2", .data = (void *)GPIO_REG_OFFSET_V2},
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, dwapb_of_match);
static const struct acpi_device_id dwapb_acpi_match[] = {
{"HISI0181", GPIO_REG_OFFSET_V1},
{"APMC0D07", GPIO_REG_OFFSET_V1},
{"APMC0D81", GPIO_REG_OFFSET_V2},
{ }
};
MODULE_DEVICE_TABLE(acpi, dwapb_acpi_match);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
static int dwapb_gpio_probe(struct platform_device *pdev)
{
unsigned int i;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
struct dwapb_gpio *gpio;
int err;
struct dwapb_platform_data *pdata;
struct device *dev = &pdev->dev;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
pdata = dwapb_gpio_get_pdata(dev);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
return -ENOMEM;
gpio->dev = &pdev->dev;
gpio->nr_ports = pdata->nports;
err = dwapb_get_reset(gpio);
if (err)
return err;
gpio->ports = devm_kcalloc(&pdev->dev, gpio->nr_ports,
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
sizeof(*gpio->ports), GFP_KERNEL);
if (!gpio->ports)
return -ENOMEM;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
gpio->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(gpio->regs))
return PTR_ERR(gpio->regs);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
err = dwapb_get_clks(gpio);
if (err)
return err;
gpio->flags = (uintptr_t)device_get_match_data(dev);
for (i = 0; i < gpio->nr_ports; i++) {
err = dwapb_gpio_add_port(gpio, &pdata->properties[i], i);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
if (err)
return err;
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
}
platform_set_drvdata(pdev, gpio);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int dwapb_gpio_suspend(struct device *dev)
{
struct dwapb_gpio *gpio = dev_get_drvdata(dev);
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
struct gpio_chip *gc = &gpio->ports[0].gc;
unsigned long flags;
int i;
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
for (i = 0; i < gpio->nr_ports; i++) {
unsigned int offset;
unsigned int idx = gpio->ports[i].idx;
struct dwapb_context *ctx = gpio->ports[i].ctx;
offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_STRIDE;
ctx->dir = dwapb_read(gpio, offset);
offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_STRIDE;
ctx->data = dwapb_read(gpio, offset);
offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_STRIDE;
ctx->ext = dwapb_read(gpio, offset);
/* Only port A can provide interrupts */
if (idx == 0) {
ctx->int_mask = dwapb_read(gpio, GPIO_INTMASK);
ctx->int_en = dwapb_read(gpio, GPIO_INTEN);
ctx->int_pol = dwapb_read(gpio, GPIO_INT_POLARITY);
ctx->int_type = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);
ctx->int_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
/* Mask out interrupts */
dwapb_write(gpio, GPIO_INTMASK, ~ctx->wake_en);
}
}
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
return 0;
}
static int dwapb_gpio_resume(struct device *dev)
{
struct dwapb_gpio *gpio = dev_get_drvdata(dev);
gpio: generic: factor into gpio_chip struct The separate struct bgpio_chip has been a pain to handle, both by being confusingly similar in name to struct gpio_chip and for being contained inside a struct so that struct gpio_chip is contained in a struct contained in a struct, making several steps of dereferencing necessary. Make things simpler: include the fields directly into <linux/gpio/driver.h>, #ifdef:ed for CONFIG_GENERIC_GPIO, and get rid of the <linux/basic_mmio_gpio.h> altogether. Prefix some of the member variables with bgpio_* and add proper kerneldoc while we're at it. Modify all users to handle the change and use a struct gpio_chip directly. And while we're at it: replace all container_of() dereferencing by gpiochip_get_data() and registering the gpio_chip with gpiochip_add_data(). Cc: arm@kernel.org Cc: Alexander Shiyan <shc_work@mail.ru> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Kukjin Kim <kgene@kernel.org> Cc: Alexandre Courbot <gnurou@gmail.com> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sudeep Holla <sudeep.holla@arm.com> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Olof Johansson <olof@lixom.net> Cc: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> Cc: Rabin Vincent <rabin@rab.in> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-omap@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org Cc: bcm-kernel-feedback-list@broadcom.com Acked-by: Gregory Fong <gregory.0xf0@gmail.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-12-04 21:02:58 +08:00
struct gpio_chip *gc = &gpio->ports[0].gc;
unsigned long flags;
int i, err;
err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks);
if (err) {
dev_err(gpio->dev, "Cannot reenable APB/Debounce clocks\n");
return err;
}
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
for (i = 0; i < gpio->nr_ports; i++) {
unsigned int offset;
unsigned int idx = gpio->ports[i].idx;
struct dwapb_context *ctx = gpio->ports[i].ctx;
offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_STRIDE;
dwapb_write(gpio, offset, ctx->data);
offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_STRIDE;
dwapb_write(gpio, offset, ctx->dir);
offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_STRIDE;
dwapb_write(gpio, offset, ctx->ext);
/* Only port A can provide interrupts */
if (idx == 0) {
dwapb_write(gpio, GPIO_INTTYPE_LEVEL, ctx->int_type);
dwapb_write(gpio, GPIO_INT_POLARITY, ctx->int_pol);
dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, ctx->int_deb);
dwapb_write(gpio, GPIO_INTEN, ctx->int_en);
dwapb_write(gpio, GPIO_INTMASK, ctx->int_mask);
/* Clear out spurious interrupts */
dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff);
}
}
gpio: use raw spinlock for gpio chip shadowed data In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency as the lockdep report shows. __irq_set_handler irq_get_desc_buslock __irq_get_desc_lock raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here __irq_do_set_handler mask_ack_irq dwapb_irq_ack spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock irq_put_desc_busunlock Replace with a raw lock to avoid BUGs. This lock is only used to access registers, and It's safe to replace with the raw lock without bad influence. [ 15.090359][ T1] ============================= [ 15.090365][ T1] [ BUG: Invalid wait context ] [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted [ 15.090386][ T1] ----------------------------- [ 15.090392][ T1] swapper/0/1 is trying to lock: [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090470][ T1] other info that might help us debug this: [ 15.090477][ T1] context-{5:5} [ 15.090485][ T1] 3 locks held by swapper/0/1: [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104 [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4 [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090654][ T1] stack backtrace: [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3 [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT) [ 15.090692][ T1] Call trace: ...... [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28 [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300 [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c [ 15.090864][ T1] __irq_set_handler+0x74/0x114 [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58 [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644 Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Doug Berger <opendmb@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(dwapb_gpio_pm_ops, dwapb_gpio_suspend,
dwapb_gpio_resume);
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
static struct platform_driver dwapb_gpio_driver = {
.driver = {
.name = DWAPB_DRIVER_NAME,
.pm = &dwapb_gpio_pm_ops,
.of_match_table = dwapb_of_match,
.acpi_match_table = dwapb_acpi_match,
gpio: add a driver for the Synopsys DesignWare APB GPIO block The Synopsys DesignWare block is used in some ARM devices (picoxcell) and can be configured to provide multiple banks of GPIO pins. v12: - Add irq_startup/shutdown - do irq_create_mapping() in probe, irq_find_mapping() in to_irq() - Adjust mappings to show support for 1 gpio per port. - gpio-cells = <1> v11: - Use NULL when checking existence of 'interrupts' property - Bindings descriptions cleanup v10: - in documentation nr-gpio -> nr-gpios v9: - cleanup in dt bindings doc - use of_get_child_count() v8: - remove socfpga.dtsi changes - minor cleanup in devicetree documentation v7: - use irq_generic_chip - support one irq per gpio line or one irq for many - s/bank/port/ and other cleanup v6: - (atull) squash the set of patches - use linear irq domain - build fixes. Original driver was reviewed on v3.2. - Fix setting irq edge type for 'rising' and 'both'. - Support as a loadable module. - Use bgpio_chip's spinlock during register access. - Clean up register names to match spec - s/bank/port/ because register names use the word 'port' - s/nr-gpio/nr-gpios/ - don't get/put the of_node - remove signoffs/acked-by's because of changes - other cleanup v5: - handle sparse bank population correctly v3: - depend on rather than select IRQ_DOMAIN - split IRQ support into a separate patch v2: - use Rob Herring's irqdomain in generic irq chip patches - use reg property to indicate bank index - support irqs on both edges based on LinusW's u300 driver Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Alan Tull <atull@altera.com> Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2014-02-26 07:01:01 +08:00
},
.probe = dwapb_gpio_probe,
};
module_platform_driver(dwapb_gpio_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamie Iles");
MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver");
MODULE_ALIAS("platform:" DWAPB_DRIVER_NAME);