gpio: dwapb: Clean up the driver and a fix
Subsystems (2)
cover gpio: dwapb: Clean up the driver and a fix
It appears that GPIO DW APB driver wasn't touched for a long time. Here is the fix for long standing issue, i.e. missed module alias to make the driver be loaded automatically.
On top of above a lot small clean ups here and there.
The series based on the v3 by Serge Semin which he sent earlier.
Driver has been tested on Intel Galileo Gen2 with AT25 SPI EEPROM using it for a chip select.
Andy Shevchenko (13):
gpio: dwapb: Append MODULE_ALIAS for platform driver
gpio: dwapb: Refactor IRQ handler
gpio: dwapb: set default handler to be handle_bad_irq()
gpio: dwapb: Deduplicate IRQ resource management
gpio: dwapb: Convert to use irqd_to_hwirq()
gpio: dwapb: Use device_get_match_data() to simplify code
gpio: dwapb: Convert to use IRQ core provided macros
gpio: dwapb: Switch to more usual pattern of RMW in
dwapb_gpio_set_debounce()
gpio: dwapb: Drop bogus BUG_ON()s
gpio: dwapb: Drop of_match_ptr() & ACPI_PTR() calls
gpio: dwapb: Split out dwapb_get_irq() helper
gpio: dwapb: Use positive conditional in dwapb_configure_irqs()
gpio: dwapb: Amend indentation in some cases
drivers/gpio/gpio-dwapb.c | 205 +++++++++++++++----------------------- 1 file changed, 79 insertions(+), 126 deletions(-)
Signature · 1 line
2.25.1
PATCH 1/13 gpio: dwapb: Append MODULE_ALIAS for platform driver
The commit 3d2613c4289f
("GPIO: gpio-dwapb: Enable platform driver binding to MFD driver")
introduced a use of the platform driver but missed to add the following line to it:
MODULE_ALIAS("platform:gpio-dwapb");
Add this to get driver loaded automatically if platform device is registered.
--- drivers/gpio/gpio-dwapb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/gpio/gpio-dwapb.c +6 -3
@@ -49,7 +49,9 @@#define GPIO_EXT_PORTC 0x58#define GPIO_EXT_PORTD 0x5c +#define DWAPB_DRIVER_NAME "gpio-dwapb"#define DWAPB_MAX_PORTS 4 +#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 */
@@ -400,7 +402,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,return ; err =irq_alloc_domain_generic_chips (gpio->domain, ngpio,2 , -"gpio-dwapb" , handle_level_irq, +DWAPB_DRIVER_NAME , handle_level_irq,IRQ_NOREQUEST ,0 ,IRQ_GC_INIT_NESTED_LOCK );if (err) {
@@ -457,7 +459,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,*/ err =devm_request_irq (gpio->dev, pp->irq[0 ], dwapb_irq_handler_mfd, -IRQF_SHARED ,"gpio-dwapb-mfd" , gpio); +IRQF_SHARED ,DWAPB_DRIVER_NAME , gpio);if (err) {dev_err (gpio->dev,"error requesting IRQ\n" );irq_domain_remove (gpio->domain);
@@ -847,7 +849,7 @@ static SIMPLE_DEV_PM_OPS(dwapb_gpio_pm_ops, dwapb_gpio_suspend,static struct platform_driver dwapb_gpio_driver = { .driver = { - .name ="gpio-dwapb" , + .name =DWAPB_DRIVER_NAME , .pm = &dwapb_gpio_pm_ops, .of_match_table =of_match_ptr (dwapb_of_match), .acpi_match_table =ACPI_PTR (dwapb_acpi_match),
@@ -861,3 +863,4 @@ 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 );
Signature · 1 line
2.25.1
Re: [PATCH v1 01/13] gpio: dwapb: Append MODULE_ALIAS for platform driver
Quoted 7 lines · Andy Shevchenko
The commit
3d2613c4289f
("GPIO: gpio-dwapb: Enable platform driver binding to MFD driver")
introduced a use of the platform driver but missed to add the following line to it:
MODULE_ALIAS("platform:gpio-dwapb");Add this to get driver loaded automatically if platform device is registered.
Looks good. Thanks.
Quoted 56 lines
Fixes 3d2613c4289f ("GPIO: gpio-dwapb: Enable platform driver binding to MFD driver")Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)drivers/gpio/gpio-dwapb.c +6
-3@@ -49,7 +49,9 @@#define GPIO_EXT_PORTC 0x58#define GPIO_EXT_PORTD 0x5c +#define DWAPB_DRIVER_NAME "gpio-dwapb"#define DWAPB_MAX_PORTS 4 +#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 */ @@ -400,7 +402,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,return ; err =irq_alloc_domain_generic_chips (gpio->domain, ngpio,2 , -"gpio-dwapb" , handle_level_irq, +DWAPB_DRIVER_NAME , handle_level_irq,IRQ_NOREQUEST ,0 ,IRQ_GC_INIT_NESTED_LOCK );if (err) {@@ -457,7 +459,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,*/ err =devm_request_irq (gpio->dev, pp->irq[0 ], dwapb_irq_handler_mfd, -IRQF_SHARED ,"gpio-dwapb-mfd" , gpio); +IRQF_SHARED ,DWAPB_DRIVER_NAME , gpio);if (err) {dev_err (gpio->dev,"error requesting IRQ\n" );irq_domain_remove (gpio->domain);@@ -847,7 +849,7 @@ static SIMPLE_DEV_PM_OPS(dwapb_gpio_pm_ops, dwapb_gpio_suspend,static struct platform_driver dwapb_gpio_driver = { .driver = { - .name ="gpio-dwapb" , + .name =DWAPB_DRIVER_NAME , .pm = &dwapb_gpio_pm_ops, .of_match_table =of_match_ptr (dwapb_of_match), .acpi_match_table =ACPI_PTR (dwapb_acpi_match),@@ -861,3 +863,4 @@ 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 );Signature · 1 line
2.25.1
PATCH 2/13 gpio: dwapb: Refactor IRQ handler
In reply to Andy ShevchenkoRefactor IRQ handler in order to:
- enter and exit chained IRQ
- use for_each_set_bit() helper
--- drivers/gpio/gpio-dwapb.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
drivers/gpio/gpio-dwapb.c +9 -11
@@ -193,22 +193,21 @@ static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)static u32 dwapb_do_irq (struct dwapb_gpio *gpio) { -u32 irq_status =dwapb_read (gpio,GPIO_INTSTATUS ); -u32 ret = irq_status; +unsigned long irq_status; +int hwirq; -while (irq_status) { -int hwirq =fls (irq_status) -1 ; + irq_status =dwapb_read (gpio,GPIO_INTSTATUS ); +for_each_set_bit (hwirq, &irq_status,32 ) {int gpio_irq =irq_find_mapping (gpio->domain, hwirq); +u32 irq_type =irq_get_trigger_type (gpio_irq);generic_handle_irq (gpio_irq); - irq_status &= ~BIT (hwirq); -if ((irq_get_trigger_type (gpio_irq) &IRQ_TYPE_SENSE_MASK ) - ==IRQ_TYPE_EDGE_BOTH ) +if ((irq_type &IRQ_TYPE_SENSE_MASK ) ==IRQ_TYPE_EDGE_BOTH )dwapb_toggle_trigger (gpio, hwirq); } -return ret; +return irq_status; }static void dwapb_irq_handler (struct irq_desc *desc)
@@ -216,10 +215,9 @@ 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); - -if (chip->irq_eoi) - chip->irq_eoi (irq_desc_get_irq_data (desc)); +chained_irq_exit (chip, desc); }static void dwapb_irq_enable (struct irq_data *d)
Signature · 1 line
2.25.1
Re: [PATCH v1 02/13] gpio: dwapb: Refactor IRQ handler
Quoted 3 lines · Andy Shevchenko
Refactor IRQ handler in order to:
- enter and exit chained IRQ
- usefor_each_set_bit()helper
Please split these two changes into the dedicated patches.
After this
Quoted 56 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)drivers/gpio/gpio-dwapb.c +9
-11@@ -193,22 +193,21 @@ static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)static u32 dwapb_do_irq (struct dwapb_gpio *gpio) { -u32 irq_status =dwapb_read (gpio,GPIO_INTSTATUS ); -u32 ret = irq_status; +unsigned long irq_status; +int hwirq; -while (irq_status) { -int hwirq =fls (irq_status) -1 ; + irq_status =dwapb_read (gpio,GPIO_INTSTATUS ); +for_each_set_bit (hwirq, &irq_status,32 ) {int gpio_irq =irq_find_mapping (gpio->domain, hwirq); +u32 irq_type =irq_get_trigger_type (gpio_irq);generic_handle_irq (gpio_irq); - irq_status &= ~BIT (hwirq); -if ((irq_get_trigger_type (gpio_irq) &IRQ_TYPE_SENSE_MASK ) - ==IRQ_TYPE_EDGE_BOTH ) +if ((irq_type &IRQ_TYPE_SENSE_MASK ) ==IRQ_TYPE_EDGE_BOTH )dwapb_toggle_trigger (gpio, hwirq); } -return ret; +return irq_status; }static void dwapb_irq_handler (struct irq_desc *desc)@@ -216,10 +215,9 @@ 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); - -if (chip->irq_eoi) - chip->irq_eoi (irq_desc_get_irq_data (desc)); +chained_irq_exit (chip, desc); }static void dwapb_irq_enable (struct irq_data *d)Signature · 1 line
2.25.1
Re: [PATCH v1 02/13] gpio: dwapb: Refactor IRQ handler
Quoted 6 lines · Serge Semin
Quoted 3 lines · Andy Shevchenko
Refactor IRQ handler in order to:
- enter and exit chained IRQ
- usefor_each_set_bit()helperPlease split these two changes into the dedicated patches.
Will do in v2. Hope your Tested-by holds.
Quoted 2 lines
After this
Reviewed-by Serge Semin <[email protected]>
Thanks!
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH 3/13 gpio: dwapb: set default handler to be handle_bad_irq()
In reply to Andy ShevchenkoWe switch the default handler to be handle_bad_irq() instead of handle_level_irq(), though for now apply it later in the code, to make the difference between IRQ chips more visible.
--- drivers/gpio/gpio-dwapb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpio/gpio-dwapb.c +2 -1
@@ -400,7 +400,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,return ; err =irq_alloc_domain_generic_chips (gpio->domain, ngpio,2 , -DWAPB_DRIVER_NAME , handle_level_irq, +DWAPB_DRIVER_NAME , handle_bad_irq,IRQ_NOREQUEST ,0 ,IRQ_GC_INIT_NESTED_LOCK );if (err) {
@@ -439,6 +439,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, } irq_gc->chip_types[0 ].type =IRQ_TYPE_LEVEL_MASK ; + irq_gc->chip_types[0 ].handler = handle_level_irq; irq_gc->chip_types[1 ].type =IRQ_TYPE_EDGE_BOTH ; irq_gc->chip_types[1 ].handler = handle_edge_irq;
Signature · 1 line
2.25.1
Re: [PATCH v1 03/13] gpio: dwapb: set default handler to be handle_bad_irq()
Quoted 3 lines · Andy Shevchenko
We switch the default handler to be
handle_bad_irq()instead ofhandle_level_irq(), though for now apply it later in the code, to make the difference between IRQ chips more visible.
s/IRQ chips/IRQ types ?
Note though I'd better refactored the whole dwapb_configure_irqs() method with using GPIOlib irqchip API, which is preferred by the current GPIO subsystem. This isn't a subject for this series. Just to note, that such change is very actual.
-Sergey
Quoted 30 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/gpio/gpio-dwapb.c +2
-1@@ -400,7 +400,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,return ; err =irq_alloc_domain_generic_chips (gpio->domain, ngpio,2 , -DWAPB_DRIVER_NAME , handle_level_irq, +DWAPB_DRIVER_NAME , handle_bad_irq,IRQ_NOREQUEST ,0 ,IRQ_GC_INIT_NESTED_LOCK );if (err) {@@ -439,6 +439,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, } irq_gc->chip_types[0 ].type =IRQ_TYPE_LEVEL_MASK ; + irq_gc->chip_types[0 ].handler = handle_level_irq; irq_gc->chip_types[1 ].type =IRQ_TYPE_EDGE_BOTH ; irq_gc->chip_types[1 ].handler = handle_edge_irq;Signature · 1 line
2.25.1
Re: [PATCH v1 03/13] gpio: dwapb: set default handler to be handle_bad_irq()
Quoted 6 lines · Serge Semin
Quoted 3 lines · Andy Shevchenko
We switch the default handler to be
handle_bad_irq()instead ofhandle_level_irq(), though for now apply it later in the code, to make the difference between IRQ chips more visible.s/IRQ chips/IRQ types ?
Actually IRQ chips. The code instantiates two IRQ chips.
Quoted 1 line
Reviewed-by Serge Semin <[email protected]>
Thanks!
Quoted 4 lines
Note though I'd better refactored the whole
dwapb_configure_irqs()method with using GPIOlib irqchip API, which is preferred by the current GPIO subsystem. This isn't a subject for this series. Just to note, that such change is very actual.
I know, but it's indeed out of scope of this series.
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH 4/13 gpio: dwapb: Deduplicate IRQ resource management
In reply to Andy ShevchenkoGPIO library provides default IRQ resource management hooks, there is no need to repeat this in the individual driver.
Remove them for good.
--- drivers/gpio/gpio-dwapb.c | 27 --------------------------- 1 file changed, 27 deletions(-)
drivers/gpio/gpio-dwapb.c +0 -27
@@ -250,31 +250,6 @@ static void dwapb_irq_disable(struct irq_data *d)spin_unlock_irqrestore (&gc->bgpio_lock, flags); } -static int dwapb_irq_reqres (struct irq_data *d) -{ -struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d); -struct dwapb_gpio *gpio = igc->private; -struct gpio_chip *gc = &gpio->ports[0 ].gc; -int ret; - - ret =gpiochip_lock_as_irq (gc,irqd_to_hwirq (d)); -if (ret) { -dev_err (gpio->dev,"unable to lock HW IRQ %lu for IRQ\n" , -irqd_to_hwirq (d)); -return ret; - } -return 0 ; -} - -static void dwapb_irq_relres (struct irq_data *d) -{ -struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d); -struct dwapb_gpio *gpio = igc->private; -struct gpio_chip *gc = &gpio->ports[0 ].gc; - -gpiochip_unlock_as_irq (gc,irqd_to_hwirq (d)); -} -static int dwapb_irq_set_type (struct irq_data *d,u32 type) {struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d);
@@ -428,8 +403,6 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, ct->chip.irq_set_type = dwapb_irq_set_type; ct->chip.irq_enable = dwapb_irq_enable; ct->chip.irq_disable = dwapb_irq_disable; - ct->chip.irq_request_resources = dwapb_irq_reqres; - ct->chip.irq_release_resources = dwapb_irq_relres;#ifdef CONFIG_PM_SLEEP ct->chip.irq_set_wake = dwapb_irq_set_wake;#endif
Signature · 1 line
2.25.1
Re: [PATCH v1 04/13] gpio: dwapb: Deduplicate IRQ resource management
Quoted 4 lines · Andy Shevchenko
GPIO library provides default IRQ resource management hooks, there is no need to repeat this in the individual driver.
Remove them for good.
Great catch. Thanks.
Quoted 54 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 27 --------------------------- 1 file changed, 27 deletions(-)drivers/gpio/gpio-dwapb.c +0
-27@@ -250,31 +250,6 @@ static void dwapb_irq_disable(struct irq_data *d)spin_unlock_irqrestore (&gc->bgpio_lock, flags); } -static int dwapb_irq_reqres (struct irq_data *d) -{ -struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d); -struct dwapb_gpio *gpio = igc->private; -struct gpio_chip *gc = &gpio->ports[0 ].gc; -int ret; - - ret =gpiochip_lock_as_irq (gc,irqd_to_hwirq (d)); -if (ret) { -dev_err (gpio->dev,"unable to lock HW IRQ %lu for IRQ\n" , -irqd_to_hwirq (d)); -return ret; - } -return 0 ; -} - -static void dwapb_irq_relres (struct irq_data *d) -{ -struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d); -struct dwapb_gpio *gpio = igc->private; -struct gpio_chip *gc = &gpio->ports[0 ].gc; - -gpiochip_unlock_as_irq (gc,irqd_to_hwirq (d)); -} -static int dwapb_irq_set_type (struct irq_data *d,u32 type) {struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d);@@ -428,8 +403,6 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, ct->chip.irq_set_type = dwapb_irq_set_type; ct->chip.irq_enable = dwapb_irq_enable; ct->chip.irq_disable = dwapb_irq_disable; - ct->chip.irq_request_resources = dwapb_irq_reqres; - ct->chip.irq_release_resources = dwapb_irq_relres;#ifdef CONFIG_PM_SLEEP ct->chip.irq_set_wake = dwapb_irq_set_wake;#endif Signature · 1 line
2.25.1
PATCH 5/13 gpio: dwapb: Convert to use irqd_to_hwirq()
In reply to Andy ShevchenkoConvert to use irqd_to_hwirq() instead of direct access to the hwirq member.
--- drivers/gpio/gpio-dwapb.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/gpio/gpio-dwapb.c +8 -6
@@ -230,7 +230,7 @@ static void dwapb_irq_enable(struct irq_data *d)spin_lock_irqsave (&gc->bgpio_lock, flags); val =dwapb_read (gpio,GPIO_INTEN ); - val |=BIT (d->hwirq); + val |=BIT (irqd_to_hwirq (d));dwapb_write (gpio,GPIO_INTEN , val);spin_unlock_irqrestore (&gc->bgpio_lock, flags); }
@@ -245,7 +245,7 @@ static void dwapb_irq_disable(struct irq_data *d)spin_lock_irqsave (&gc->bgpio_lock, flags); val =dwapb_read (gpio,GPIO_INTEN ); - val &= ~BIT (d->hwirq); + val &= ~BIT (irqd_to_hwirq (d));dwapb_write (gpio,GPIO_INTEN , val);spin_unlock_irqrestore (&gc->bgpio_lock, flags); }
@@ -255,8 +255,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d);struct dwapb_gpio *gpio = igc->private;struct gpio_chip *gc = &gpio->ports[0 ].gc; -int bit = d->hwirq;unsigned long level, polarity, flags; +u32 bit =irqd_to_hwirq (d);if (type & ~(IRQ_TYPE_EDGE_RISING |IRQ_TYPE_EDGE_FALLING |IRQ_TYPE_LEVEL_HIGH |IRQ_TYPE_LEVEL_LOW ))
@@ -305,11 +305,12 @@ static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d);struct dwapb_gpio *gpio = igc->private;struct dwapb_context *ctx = gpio->ports[0 ].ctx; +u32 bit =irqd_to_hwirq (d);if (enable) - ctx->wake_en |=BIT (d->hwirq); + ctx->wake_en |=BIT (bit);else - ctx->wake_en &= ~BIT (d->hwirq); + ctx->wake_en &= ~BIT (bit);return 0 ; }
@@ -365,8 +366,9 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,struct gpio_chip *gc = &port->gc;struct fwnode_handle *fwnode = pp->fwnode;struct irq_chip_generic *irq_gc =NULL ; -unsigned int hwirq, ngpio = gc->ngpio; +unsigned int ngpio = gc->ngpio;struct irq_chip_type *ct; +irq_hw_number_t hwirq;int err, i; gpio->domain = irq_domain_create_linear(fwnode, ngpio,
Signature · 1 line
2.25.1
Re: [PATCH v1 05/13] gpio: dwapb: Convert to use irqd_to_hwirq()
Quoted 30 lines · Andy Shevchenko
Convert to use
irqd_to_hwirq()instead of direct access to the hwirq member.Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)drivers/gpio/gpio-dwapb.c +2
-2@@ -230,7 +230,7 @@ static void dwapb_irq_enable(struct irq_data *d)spin_lock_irqsave (&gc->bgpio_lock, flags); val =dwapb_read (gpio,GPIO_INTEN ); - val |=BIT (d->hwirq); + val |=BIT (irqd_to_hwirq (d));dwapb_write (gpio,GPIO_INTEN , val);spin_unlock_irqrestore (&gc->bgpio_lock, flags); }@@ -245,7 +245,7 @@ static void dwapb_irq_disable(struct irq_data *d)spin_lock_irqsave (&gc->bgpio_lock, flags); val =dwapb_read (gpio,GPIO_INTEN ); - val &= ~BIT (d->hwirq); + val &= ~BIT (irqd_to_hwirq (d));dwapb_write (gpio,GPIO_INTEN , val);spin_unlock_irqrestore (&gc->bgpio_lock, flags); }
drivers/gpio/gpio-dwapb.c static int dwapb_irq_set_type(struct irq_data *d, u32 type) · line 259
Quoted 6 lines
drivers/gpio/gpio-dwapb.c +1
-1@@ -255,8 +255,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d);struct dwapb_gpio *gpio = igc->private;struct gpio_chip *gc = &gpio->ports[0 ].gc; -int bit = d->hwirq;unsigned long level, polarity, flags; +u32 bit =irqd_to_hwirq (d);
I'm not saying that the rest of the driver code is highly coherent with ideal design and style. But here I don't really see a point in converting the type to u32. As I see it int-like type is more appropriate since we don't need to signify the data type width in this context.
-Sergey
Quoted 32 lines
drivers/gpio/gpio-dwapb.c +5
-3if (type & ~(IRQ_TYPE_EDGE_RISING |IRQ_TYPE_EDGE_FALLING |IRQ_TYPE_LEVEL_HIGH |IRQ_TYPE_LEVEL_LOW ))@@ -305,11 +305,12 @@ static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)struct irq_chip_generic *igc =irq_data_get_irq_chip_data (d);struct dwapb_gpio *gpio = igc->private;struct dwapb_context *ctx = gpio->ports[0 ].ctx; +u32 bit =irqd_to_hwirq (d);if (enable) - ctx->wake_en |=BIT (d->hwirq); + ctx->wake_en |=BIT (bit);else - ctx->wake_en &= ~BIT (d->hwirq); + ctx->wake_en &= ~BIT (bit);return 0 ; }@@ -365,8 +366,9 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,struct gpio_chip *gc = &port->gc;struct fwnode_handle *fwnode = pp->fwnode;struct irq_chip_generic *irq_gc =NULL ; -unsigned int hwirq, ngpio = gc->ngpio; +unsigned int ngpio = gc->ngpio;struct irq_chip_type *ct; +irq_hw_number_t hwirq;int err, i; gpio->domain = irq_domain_create_linear(fwnode, ngpio,Signature · 1 line
2.25.1
Re: [PATCH v1 05/13] gpio: dwapb: Convert to use irqd_to_hwirq()
Quoted 5 lines · Serge Semin
Quoted 3 lines · Andy Shevchenko
Convert to use
irqd_to_hwirq()instead of direct access to the hwirq member.drivers/gpio/gpio-dwapb.c +0
-1-int bit = d->hwirq;
Quoted 8 lines
Review
Quoted 1 line
(quoted diff) +1
-0+ u32 bit = irqd_to_hwirq(d);I'm not saying that the rest of the driver code is highly coherent with ideal design and style. But here I don't really see a point in converting the type to u32. As I see it int-like type is more appropriate since we don't need to signify the data type width in this context.
Review
Quoted 1 line
(quoted diff) +1
-0+ u32 bit = irqd_to_hwirq(d);
The idea is that it corresponds the hardware register width. But, i think the proper one is irq_hw_number_t as return type in all cases.
Let me check this and fix accordingly.
Quoted 1 line
Quoted 1 line
drivers/gpio/gpio-dwapb.c +1
-0+irq_hw_number_t hwirq;
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH 6/13 gpio: dwapb: Use device_get_match_data() to simplify code
In reply to Andy ShevchenkoUse device_get_match_data() here to simplify the code a bit.
--- drivers/gpio/gpio-dwapb.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)
drivers/gpio/gpio-dwapb.c +1 -12
@@ -683,18 +683,7 @@ static int dwapb_gpio_probe(struct platform_device *pdev)return err; } - gpio->flags =0 ; -if (dev->of_node) { - gpio->flags = (uintptr_t )of_device_get_match_data (dev); - }else if (has_acpi_companion (dev)) { -const struct acpi_device_id *acpi_id; - - acpi_id =acpi_match_device (dwapb_acpi_match, dev); -if (acpi_id) { -if (acpi_id->driver_data) - gpio->flags = acpi_id->driver_data; - } - } + 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);
Signature · 1 line
2.25.1
Re: [PATCH v1 06/13] gpio: dwapb: Use device_get_match_data() to simplify code
Quoted 1 line · Andy Shevchenko
Use
device_get_match_data()here to simplify the code a bit.
Nice simplification. Thanks.
Quoted 33 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)drivers/gpio/gpio-dwapb.c +1
-12@@ -683,18 +683,7 @@ static int dwapb_gpio_probe(struct platform_device *pdev)return err; } - gpio->flags =0 ; -if (dev->of_node) { - gpio->flags = (uintptr_t )of_device_get_match_data (dev); - }else if (has_acpi_companion (dev)) { -const struct acpi_device_id *acpi_id; - - acpi_id =acpi_match_device (dwapb_acpi_match, dev); -if (acpi_id) { -if (acpi_id->driver_data) - gpio->flags = acpi_id->driver_data; - } - } + 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);Signature · 1 line
2.25.1
PATCH 7/13 gpio: dwapb: Convert to use IRQ core provided macros
In reply to Andy ShevchenkoIRQ core provides macros such as IRQ_RETVAL().
Convert code to use them.
--- drivers/gpio/gpio-dwapb.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/gpio/gpio-dwapb.c +2 -8
@@ -258,8 +258,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)unsigned long level, polarity, flags;u32 bit =irqd_to_hwirq (d); -if (type & ~(IRQ_TYPE_EDGE_RISING |IRQ_TYPE_EDGE_FALLING | -IRQ_TYPE_LEVEL_HIGH |IRQ_TYPE_LEVEL_LOW )) +if (type & ~IRQ_TYPE_SENSE_MASK )return -EINVAL ;spin_lock_irqsave (&gc->bgpio_lock, flags);
@@ -351,12 +350,7 @@ static int dwapb_gpio_set_config(struct gpio_chip *gc, unsigned offset,static irqreturn_t dwapb_irq_handler_mfd (int irq,void *dev_id) { -u32 worked; -struct dwapb_gpio *gpio = dev_id; - - worked =dwapb_do_irq (gpio); - -return worked ?IRQ_HANDLED :IRQ_NONE ; +return IRQ_RETVAL (dwapb_do_irq (dev_id)); } static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
Signature · 1 line
2.25.1
Re: [PATCH v1 07/13] gpio: dwapb: Convert to use IRQ core provided macros
Quoted 2 lines · Andy Shevchenko
IRQ core provides macros such as
IRQ_RETVAL().
Convert code to use them.
Looks good. Thanks.
Quoted 37 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)drivers/gpio/gpio-dwapb.c +2
-8@@ -258,8 +258,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)unsigned long level, polarity, flags;u32 bit =irqd_to_hwirq (d); -if (type & ~(IRQ_TYPE_EDGE_RISING |IRQ_TYPE_EDGE_FALLING | -IRQ_TYPE_LEVEL_HIGH |IRQ_TYPE_LEVEL_LOW )) +if (type & ~IRQ_TYPE_SENSE_MASK )return -EINVAL ;spin_lock_irqsave (&gc->bgpio_lock, flags);@@ -351,12 +350,7 @@ static int dwapb_gpio_set_config(struct gpio_chip *gc, unsigned offset,static irqreturn_t dwapb_irq_handler_mfd (int irq,void *dev_id) { -u32 worked; -struct dwapb_gpio *gpio = dev_id; - - worked =dwapb_do_irq (gpio); - -return worked ?IRQ_HANDLED :IRQ_NONE ; +return IRQ_RETVAL (dwapb_do_irq (dev_id)); } static void dwapb_configure_irqs(struct dwapb_gpio *gpio,Signature · 1 line
2.25.1
PATCH 8/13 gpio: dwapb: Switch to more usual pattern of RMW in dwapb_gpio_set_debounce()
In reply to Andy ShevchenkoMore usual pattern is to prepare value and then write it in a single place. Switch code in dwapb_gpio_set_debounce() to it.
--- drivers/gpio/gpio-dwapb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpio/gpio-dwapb.c +3 -2
@@ -327,9 +327,10 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc, val_deb =dwapb_read (gpio,GPIO_PORTA_DEBOUNCE );if (debounce) -dwapb_write (gpio,GPIO_PORTA_DEBOUNCE , val_deb | mask); + val_deb |= mask;else -dwapb_write (gpio,GPIO_PORTA_DEBOUNCE , val_deb & ~mask); + val_deb &= ~mask; +dwapb_write (gpio,GPIO_PORTA_DEBOUNCE , val_deb);spin_unlock_irqrestore (&gc->bgpio_lock, flags);
Signature · 1 line
2.25.1
Re: [PATCH v1 08/13] gpio: dwapb: Switch to more usual pattern of RMW in dwapb_gpio_set_debounce()
Quoted 2 lines · Andy Shevchenko
More usual pattern is to prepare value and then write it in a single place. Switch code in
dwapb_gpio_set_debounce()to it.
Seems appropriate. Thanks.
Quoted 26 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)drivers/gpio/gpio-dwapb.c +3
-2@@ -327,9 +327,10 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc, val_deb =dwapb_read (gpio,GPIO_PORTA_DEBOUNCE );if (debounce) -dwapb_write (gpio,GPIO_PORTA_DEBOUNCE , val_deb | mask); + val_deb |= mask;else -dwapb_write (gpio,GPIO_PORTA_DEBOUNCE , val_deb & ~mask); + val_deb &= ~mask; +dwapb_write (gpio,GPIO_PORTA_DEBOUNCE , val_deb);spin_unlock_irqrestore (&gc->bgpio_lock, flags);Signature · 1 line
2.25.1
PATCH 9/13 gpio: dwapb: Drop bogus BUG_ON()s
In reply to Andy ShevchenkoThere is no case when no context is provided in the ->suspend() and ->resume() hooks. Moreover, BUG_ON() is harmful to user and makes kernel inoperable after the crash. Drop the BUG_ON()s for good.
--- drivers/gpio/gpio-dwapb.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/gpio/gpio-dwapb.c +0 -4
@@ -723,8 +723,6 @@ static int dwapb_gpio_suspend(struct device *dev)unsigned int idx = gpio->ports[i].idx;struct dwapb_context *ctx = gpio->ports[i].ctx; -BUG_ON (!ctx); - offset =GPIO_SWPORTA_DDR + idx *GPIO_SWPORT_DDR_STRIDE ; ctx->dir =dwapb_read (gpio, offset);
@@ -773,8 +771,6 @@ static int dwapb_gpio_resume(struct device *dev)unsigned int idx = gpio->ports[i].idx;struct dwapb_context *ctx = gpio->ports[i].ctx; -BUG_ON (!ctx); - offset =GPIO_SWPORTA_DR + idx *GPIO_SWPORT_DR_STRIDE ;dwapb_write (gpio, offset, ctx->data);
Signature · 1 line
2.25.1
Re: [PATCH v1 09/13] gpio: dwapb: Drop bogus BUG_ON()s
Quoted 3 lines · Andy Shevchenko
There is no case when no context is provided in the ->suspend() and ->resume() hooks. Moreover,
BUG_ON()is harmful to user and makes kernel inoperable after the crash. Drop the BUG_ON()s for good.
Right. Thanks. Though I wouldn't name them bogus, but redundant or unnecessary instead.
Quoted 31 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 4 ---- 1 file changed, 4 deletions(-)drivers/gpio/gpio-dwapb.c +0
-4@@ -723,8 +723,6 @@ static int dwapb_gpio_suspend(struct device *dev)unsigned int idx = gpio->ports[i].idx;struct dwapb_context *ctx = gpio->ports[i].ctx; -BUG_ON (!ctx); - offset =GPIO_SWPORTA_DDR + idx *GPIO_SWPORT_DDR_STRIDE ; ctx->dir =dwapb_read (gpio, offset);@@ -773,8 +771,6 @@ static int dwapb_gpio_resume(struct device *dev)unsigned int idx = gpio->ports[i].idx;struct dwapb_context *ctx = gpio->ports[i].ctx; -BUG_ON (!ctx); - offset =GPIO_SWPORTA_DR + idx *GPIO_SWPORT_DR_STRIDE ;dwapb_write (gpio, offset, ctx->data);Signature · 1 line
2.25.1
PATCH 10/13 gpio: dwapb: Drop of_match_ptr() & ACPI_PTR() calls
In reply to Andy ShevchenkoSince we always have a table of IDs compiled in, there is no use for of_match_ptr() nor ACPI_PTR() call. Besides that it brings a warning (depending on configuration):
.../gpio-dwapb.c:638:34: warning: ‘dwapb_of_match’ defined but not used [-Wunused-const-variable=]
638 | static const struct of_device_id dwapb_of_match[] = {
| ^~~~~~~~~~~~~~Get rid of them for good.
--- drivers/gpio/gpio-dwapb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpio/gpio-dwapb.c +2 -2
@@ -805,8 +805,8 @@ static struct platform_driver dwapb_gpio_driver = { .driver = { .name = DWAPB_DRIVER_NAME, .pm = &dwapb_gpio_pm_ops, - .of_match_table = of_match_ptr(dwapb_of_match), - .acpi_match_table = ACPI_PTR(dwapb_acpi_match), + .of_match_table = dwapb_of_match, + .acpi_match_table = dwapb_acpi_match, }, .probe = dwapb_gpio_probe, .remove = dwapb_gpio_remove,
Signature · 1 line
2.25.1
Re: [PATCH v1 10/13] gpio: dwapb: Drop of_match_ptr() & ACPI_PTR() calls
Quoted 9 lines · Andy Shevchenko
Since we always have a table of IDs compiled in, there is no use for
of_match_ptr()norACPI_PTR()call. Besides that it brings a warning (depending on configuration):
.../gpio-dwapb.c:638:34: warning: ‘dwapb_of_match’ defined but not used [-Wunused-const-variable=]638 | static const struct of_device_id dwapb_of_match[] = { | ^~~~~~~~~~~~~~Get rid of them for good.
Looks good. Thanks.
Quoted 24 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/gpio/gpio-dwapb.c +2
-2@@ -805,8 +805,8 @@ static struct platform_driver dwapb_gpio_driver = { .driver = { .name = DWAPB_DRIVER_NAME, .pm = &dwapb_gpio_pm_ops, - .of_match_table = of_match_ptr(dwapb_of_match), - .acpi_match_table = ACPI_PTR(dwapb_acpi_match), + .of_match_table = dwapb_of_match, + .acpi_match_table = dwapb_acpi_match, }, .probe = dwapb_gpio_probe, .remove = dwapb_gpio_remove,Signature · 1 line
2.25.1
PATCH 11/13 gpio: dwapb: Split out dwapb_get_irq() helper
In reply to Andy ShevchenkoSplit out dwapb_get_irq() helper for better readability and maintenance.
--- drivers/gpio/gpio-dwapb.c | 56 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 27 deletions(-)
drivers/gpio/gpio-dwapb.c +29 -27
@@ -528,14 +528,38 @@ static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)gpiochip_remove (&gpio->ports[m].gc); } -static struct dwapb_platform_data * -dwapb_gpio_get_pdata (struct device *dev) +static void dwapb_get_irq (struct device *dev,struct fwnode_handle *fwnode, +struct dwapb_port_property *pp) +{ +struct device_node *np =NULL ; +int j; + +if (fwnode_property_read_bool (fwnode,"interrupt-controller" )) + np =to_of_node (fwnode); + +for (j =0 ; j < pp->ngpio; j++) { + pp->irq[j] = -ENXIO ; + +if (np) + pp->irq[j] =of_irq_get (np, j); +else if (has_acpi_companion (dev)) + pp->irq[j] =platform_get_irq (to_platform_device (dev), j); + +if (pp->irq[j] >=0 ) + pp->has_irq = true; + } + +if (!pp->has_irq) +dev_warn (dev,"no irq for port%d\n" , pp->idx); +} + +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, j; +int i; nports =device_get_child_node_count (dev);if (nports ==0 )
@@ -553,8 +577,6 @@ dwapb_gpio_get_pdata(struct device *dev) i =0 ;device_for_each_child_node (dev, fwnode) { -struct device_node *np =NULL ; - pp = &pdata->properties[i++]; pp->fwnode = fwnode;
@@ -581,28 +603,8 @@ dwapb_gpio_get_pdata(struct device *dev)* Only port A can provide interrupts in all configurations of * the IP. */ -if (pp->idx !=0 ) -continue ; - -if (dev->of_node &&fwnode_property_read_bool (fwnode, -"interrupt-controller" )) { - np =to_of_node (fwnode); - } - -for (j =0 ; j < pp->ngpio; j++) { - pp->irq[j] = -ENXIO ; - -if (np) - pp->irq[j] =of_irq_get (np, j); -else if (has_acpi_companion (dev)) - pp->irq[j] =platform_get_irq (to_platform_device (dev), j); - -if (pp->irq[j] >=0 ) - pp->has_irq = true; - } - -if (!pp->has_irq) -dev_warn (dev,"no irq for port%d\n" , pp->idx); +if (pp->idx ==0 ) +dwapb_get_irq (dev, fwnode, pp); }return pdata;
Signature · 1 line
2.25.1
Re: [PATCH v1 11/13] gpio: dwapb: Split out dwapb_get_irq() helper
Quoted 1 line · Andy Shevchenko
Split out
dwapb_get_irq()helper for better readability and maintenance.
Seems appropriate. Thanks.
Quoted 95 lines
Signed-off-by Andy Shevchenko <[email protected]>--- drivers/gpio/gpio-dwapb.c | 56 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 27 deletions(-)drivers/gpio/gpio-dwapb.c +29
-27@@ -528,14 +528,38 @@ static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)gpiochip_remove (&gpio->ports[m].gc); } -static struct dwapb_platform_data * -dwapb_gpio_get_pdata (struct device *dev) +static void dwapb_get_irq (struct device *dev,struct fwnode_handle *fwnode, +struct dwapb_port_property *pp) +{ +struct device_node *np =NULL ; +int j; + +if (fwnode_property_read_bool (fwnode,"interrupt-controller" )) + np =to_of_node (fwnode); + +for (j =0 ; j < pp->ngpio; j++) { + pp->irq[j] = -ENXIO ; + +if (np) + pp->irq[j] =of_irq_get (np, j); +else if (has_acpi_companion (dev)) + pp->irq[j] =platform_get_irq (to_platform_device (dev), j); + +if (pp->irq[j] >=0 ) + pp->has_irq = true; + } + +if (!pp->has_irq) +dev_warn (dev,"no irq for port%d\n" , pp->idx); +} + +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, j; +int i; nports =device_get_child_node_count (dev);if (nports ==0 )@@ -553,8 +577,6 @@ dwapb_gpio_get_pdata(struct device *dev) i =0 ;device_for_each_child_node (dev, fwnode) { -struct device_node *np =NULL ; - pp = &pdata->properties[i++]; pp->fwnode = fwnode;@@ -581,28 +603,8 @@ dwapb_gpio_get_pdata(struct device *dev)* Only port A can provide interrupts in all configurations of * the IP. */ -if (pp->idx !=0 ) -continue ; - -if (dev->of_node &&fwnode_property_read_bool (fwnode, -"interrupt-controller" )) { - np =to_of_node (fwnode); - } - -for (j =0 ; j < pp->ngpio; j++) { - pp->irq[j] = -ENXIO ; - -if (np) - pp->irq[j] =of_irq_get (np, j); -else if (has_acpi_companion (dev)) - pp->irq[j] =platform_get_irq (to_platform_device (dev), j); - -if (pp->irq[j] >=0 ) - pp->has_irq = true; - } - -if (!pp->has_irq) -dev_warn (dev,"no irq for port%d\n" , pp->idx); +if (pp->idx ==0 ) +dwapb_get_irq (dev, fwnode, pp); }return pdata;Signature · 1 line
2.25.1
PATCH 12/13 gpio: dwapb: Use positive conditional in dwapb_configure_irqs()
In reply to Andy ShevchenkoThe negative conditionals are harder to parse by reader. Switch to positive one in dwapb_configure_irqs().
--- drivers/gpio/gpio-dwapb.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/gpio/gpio-dwapb.c +9 -9
@@ -413,15 +413,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, irq_gc->chip_types[1 ].type =IRQ_TYPE_EDGE_BOTH ; irq_gc->chip_types[1 ].handler = handle_edge_irq; -if (!pp->irq_shared) { -int i; - -for (i =0 ; i < pp->ngpio; i++) { -if (pp->irq[i] >=0 ) -irq_set_chained_handler_and_data (pp->irq[i], - dwapb_irq_handler, gpio); - } - }else { +if (pp->irq_shared) {/* * Request a shared IRQ since where MFD would have devices * using the same irq pin
@@ -435,6 +427,14 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, gpio->domain =NULL ;return ; } + }else { +int i; + +for (i =0 ; i < pp->ngpio; i++) { +if (pp->irq[i] >=0 ) +irq_set_chained_handler_and_data (pp->irq[i], + dwapb_irq_handler, gpio); + } }for (hwirq =0 ; hwirq < ngpio ; hwirq++)
Signature · 1 line
2.25.1
PATCH 13/13 gpio: dwapb: Amend indentation in some cases
In reply to Andy ShevchenkoIn some cases indentation makes code harder to read. Amend indentation in those cases despite of lines go a bit over 80 character limit.
--- drivers/gpio/gpio-dwapb.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-)
drivers/gpio/gpio-dwapb.c +9 -15
@@ -437,7 +437,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, } } -for (hwirq =0 ; hwirq < ngpio ; hwirq++) +for (hwirq =0 ; hwirq < ngpio; hwirq++)irq_create_mapping (gpio->domain, hwirq); port->gc.to_irq = dwapb_gpio_to_irq;
@@ -453,7 +453,7 @@ static void dwapb_irq_teardown(struct dwapb_gpio *gpio)if (!gpio->domain)return ; -for (hwirq =0 ; hwirq < ngpio ; hwirq++) +for (hwirq =0 ; hwirq < ngpio; hwirq++)irq_dispose_mapping (irq_find_mapping (gpio->domain, hwirq));irq_domain_remove (gpio->domain);
@@ -478,10 +478,9 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,return -ENOMEM ;#endif - 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 ); + 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 ;/* This registers 32 GPIO lines per port */ err = bgpio_init(&port->gc, gpio->dev, 4, dat, set, NULL, dirout,
@@ -582,17 +581,13 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev)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); +dev_err (dev,"missing/invalid port index for port%d\n" , i);fwnode_handle_put (fwnode);return ERR_PTR (-EINVAL ); } -if (fwnode_property_read_u32 (fwnode,"snps,nr-gpios" , - &pp->ngpio)) { -dev_info (dev, -"failed to get number of gpios for port%d\n" , - i); +if (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 =32 ; }
@@ -743,8 +738,7 @@ static int dwapb_gpio_suspend(struct device *dev) ctx->int_deb =dwapb_read (gpio,GPIO_PORTA_DEBOUNCE );/* Mask out interrupts */ -dwapb_write (gpio,GPIO_INTMASK , -0xffffffff & ~ctx->wake_en); +dwapb_write (gpio,GPIO_INTMASK ,0xffffffff & ~ctx->wake_en); } }spin_unlock_irqrestore (&gc->bgpio_lock, flags);
Signature · 1 line
2.25.1
Hello Andy
Quoted 10 lines · Andy Shevchenko
It appears that GPIO DW APB driver wasn't touched for a long time. Here is the fix for long standing issue, i.e. missed module alias to make the driver be loaded automatically.
On top of above a lot small clean ups here and there.
The series based on the v3 by Serge Semin which he sent earlier.
Driver has been tested on Intel Galileo Gen2 with AT25 SPI EEPROM using it for a chip select.
Thanks for the series. I'll review it in one-two days and test it out on our Baikal-T1-based hardware.
-Sergey
Quoted 23 lines
Andy Shevchenko (13):
gpio: dwapb: AppendMODULE_ALIASfor platform driver
gpio: dwapb: Refactor IRQ handler
gpio: dwapb: set default handler to behandle_bad_irq()
gpio: dwapb: Deduplicate IRQ resource management
gpio: dwapb: Convert to useirqd_to_hwirq()
gpio: dwapb: Usedevice_get_match_data()to simplify code
gpio: dwapb: Convert to use IRQ core provided macros
gpio: dwapb: Switch to more usual pattern of RMW in
dwapb_gpio_set_debounce()
gpio: dwapb: Drop bogus BUG_ON()s
gpio: dwapb: Dropof_match_ptr()&ACPI_PTR()calls
gpio: dwapb: Split outdwapb_get_irq()helper
gpio: dwapb: Use positive conditional indwapb_configure_irqs()
gpio: dwapb: Amend indentation in some casesdrivers/gpio/gpio-dwapb.c | 205 +++++++++++++++----------------------- 1 file changed, 79 insertions(+), 126 deletions(-)Signature · 1 line
2.25.1
Hello Andy
Quoted 10 lines · Andy Shevchenko
It appears that GPIO DW APB driver wasn't touched for a long time. Here is the fix for long standing issue, i.e. missed module alias to make the driver be loaded automatically.
On top of above a lot small clean ups here and there.
The series based on the v3 by Serge Semin which he sent earlier.
Driver has been tested on Intel Galileo Gen2 with AT25 SPI EEPROM using it for a chip select.
Thanks one more time for the series of nice cleanups. I've successfully tested it on our board with Baikal-T1 SoC, which has two DW APB IP-cores embedded with Ports A being configured as GPIOx32 and irqless GPIOx3. So for the whole series
(Note since until my series is merged in to the kernel technically I'm not the driver maintainer so I'll use the reviewers tag for now where it's relevant.)
Regards,
-Sergey
Quoted 23 lines
Andy Shevchenko (13):
gpio: dwapb: AppendMODULE_ALIASfor platform driver
gpio: dwapb: Refactor IRQ handler
gpio: dwapb: set default handler to behandle_bad_irq()
gpio: dwapb: Deduplicate IRQ resource management
gpio: dwapb: Convert to useirqd_to_hwirq()
gpio: dwapb: Usedevice_get_match_data()to simplify code
gpio: dwapb: Convert to use IRQ core provided macros
gpio: dwapb: Switch to more usual pattern of RMW in
dwapb_gpio_set_debounce()
gpio: dwapb: Drop bogus BUG_ON()s
gpio: dwapb: Dropof_match_ptr()&ACPI_PTR()calls
gpio: dwapb: Split outdwapb_get_irq()helper
gpio: dwapb: Use positive conditional indwapb_configure_irqs()
gpio: dwapb: Amend indentation in some casesdrivers/gpio/gpio-dwapb.c | 205 +++++++++++++++----------------------- 1 file changed, 79 insertions(+), 126 deletions(-)Signature · 1 line
2.25.1
Quoted 11 lines · Serge Semin
Hello Andy
Quoted 8 lines · Andy Shevchenko
It appears that GPIO DW APB driver wasn't touched for a long time. Here is the fix for long standing issue, i.e. missed module alias to make the driver be loaded automatically.
On top of above a lot small clean ups here and there.
The series based on the v3 by Serge Semin which he sent earlier.
Quoted 8 lines
Quoted 2 lines
Driver has been tested on Intel Galileo Gen2 with AT25 SPI EEPROM using it for a chip select.
Thanks one more time for the series of nice cleanups. I've successfully tested it on our board with Baikal-T1 SoC, which has two DW APB IP-cores embedded with Ports A being configured as GPIOx32 and irqless GPIOx3. So for the whole series
Tested-by Serge Semin <[email protected]>
Thank you very much.
I hope Linus will figure out how to proceed with this.
Quoted 3 lines
(Note since until my series is merged in to the kernel technically I'm not the driver maintainer so I'll use the reviewers tag for now where it's relevant.)
Even if you are not (yet) maintainer, your tags count and be appreciated.
Signature · 2 lines
With Best Regards, Andy Shevchenko