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>
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
*
|
||||
* All enquiries to support@picochip.com
|
||||
*/
|
||||
#include <linux/basic_mmio_gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
/* FIXME: for gpio_get_value(), replace this with direct register read */
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -66,7 +68,7 @@ struct dwapb_context {
|
||||
#endif
|
||||
|
||||
struct dwapb_gpio_port {
|
||||
struct bgpio_chip bgc;
|
||||
struct gpio_chip gc;
|
||||
bool is_registered;
|
||||
struct dwapb_gpio *gpio;
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -83,33 +85,26 @@ struct dwapb_gpio {
|
||||
struct irq_domain *domain;
|
||||
};
|
||||
|
||||
static inline struct dwapb_gpio_port *
|
||||
to_dwapb_gpio_port(struct bgpio_chip *bgc)
|
||||
{
|
||||
return container_of(bgc, struct dwapb_gpio_port, bgc);
|
||||
}
|
||||
|
||||
static inline u32 dwapb_read(struct dwapb_gpio *gpio, unsigned int offset)
|
||||
{
|
||||
struct bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
void __iomem *reg_base = gpio->regs;
|
||||
|
||||
return bgc->read_reg(reg_base + offset);
|
||||
return gc->read_reg(reg_base + offset);
|
||||
}
|
||||
|
||||
static inline void dwapb_write(struct dwapb_gpio *gpio, unsigned int offset,
|
||||
u32 val)
|
||||
{
|
||||
struct bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
void __iomem *reg_base = gpio->regs;
|
||||
|
||||
bgc->write_reg(reg_base + offset, val);
|
||||
gc->write_reg(reg_base + offset, val);
|
||||
}
|
||||
|
||||
static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct bgpio_chip *bgc = to_bgpio_chip(gc);
|
||||
struct dwapb_gpio_port *port = to_dwapb_gpio_port(bgc);
|
||||
struct dwapb_gpio_port *port = gpiochip_get_data(gc);
|
||||
struct dwapb_gpio *gpio = port->gpio;
|
||||
|
||||
return irq_find_mapping(gpio->domain, offset);
|
||||
@@ -119,7 +114,7 @@ static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
|
||||
{
|
||||
u32 v = dwapb_read(gpio, GPIO_INT_POLARITY);
|
||||
|
||||
if (gpio_get_value(gpio->ports[0].bgc.gc.base + offs))
|
||||
if (gpio_get_value(gpio->ports[0].gc.base + offs))
|
||||
v &= ~BIT(offs);
|
||||
else
|
||||
v |= BIT(offs);
|
||||
@@ -162,39 +157,39 @@ static void dwapb_irq_enable(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
|
||||
struct dwapb_gpio *gpio = igc->private;
|
||||
struct bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&bgc->lock, flags);
|
||||
spin_lock_irqsave(&gc->bgpio_lock, flags);
|
||||
val = dwapb_read(gpio, GPIO_INTEN);
|
||||
val |= BIT(d->hwirq);
|
||||
dwapb_write(gpio, GPIO_INTEN, val);
|
||||
spin_unlock_irqrestore(&bgc->lock, flags);
|
||||
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
|
||||
}
|
||||
|
||||
static void dwapb_irq_disable(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
|
||||
struct dwapb_gpio *gpio = igc->private;
|
||||
struct bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&bgc->lock, flags);
|
||||
spin_lock_irqsave(&gc->bgpio_lock, flags);
|
||||
val = dwapb_read(gpio, GPIO_INTEN);
|
||||
val &= ~BIT(d->hwirq);
|
||||
dwapb_write(gpio, GPIO_INTEN, val);
|
||||
spin_unlock_irqrestore(&bgc->lock, flags);
|
||||
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 bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
|
||||
if (gpiochip_lock_as_irq(&bgc->gc, irqd_to_hwirq(d))) {
|
||||
if (gpiochip_lock_as_irq(gc, irqd_to_hwirq(d))) {
|
||||
dev_err(gpio->dev, "unable to lock HW IRQ %lu for IRQ\n",
|
||||
irqd_to_hwirq(d));
|
||||
return -EINVAL;
|
||||
@@ -206,16 +201,16 @@ 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 bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
|
||||
gpiochip_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d));
|
||||
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);
|
||||
struct dwapb_gpio *gpio = igc->private;
|
||||
struct bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
int bit = d->hwirq;
|
||||
unsigned long level, polarity, flags;
|
||||
|
||||
@@ -223,7 +218,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
|
||||
IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&bgc->lock, flags);
|
||||
spin_lock_irqsave(&gc->bgpio_lock, flags);
|
||||
level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);
|
||||
polarity = dwapb_read(gpio, GPIO_INT_POLARITY);
|
||||
|
||||
@@ -254,7 +249,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
|
||||
|
||||
dwapb_write(gpio, GPIO_INTTYPE_LEVEL, level);
|
||||
dwapb_write(gpio, GPIO_INT_POLARITY, polarity);
|
||||
spin_unlock_irqrestore(&bgc->lock, flags);
|
||||
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -262,13 +257,12 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
|
||||
static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
|
||||
unsigned offset, unsigned debounce)
|
||||
{
|
||||
struct bgpio_chip *bgc = to_bgpio_chip(gc);
|
||||
struct dwapb_gpio_port *port = to_dwapb_gpio_port(bgc);
|
||||
struct dwapb_gpio_port *port = gpiochip_get_data(gc);
|
||||
struct dwapb_gpio *gpio = port->gpio;
|
||||
unsigned long flags, val_deb;
|
||||
unsigned long mask = bgc->pin2mask(bgc, offset);
|
||||
unsigned long mask = gc->pin2mask(gc, offset);
|
||||
|
||||
spin_lock_irqsave(&bgc->lock, flags);
|
||||
spin_lock_irqsave(&gc->bgpio_lock, flags);
|
||||
|
||||
val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
|
||||
if (debounce)
|
||||
@@ -276,7 +270,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
|
||||
else
|
||||
dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb & ~mask);
|
||||
|
||||
spin_unlock_irqrestore(&bgc->lock, flags);
|
||||
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -295,7 +289,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
|
||||
struct dwapb_gpio_port *port,
|
||||
struct dwapb_port_property *pp)
|
||||
{
|
||||
struct gpio_chip *gc = &port->bgc.gc;
|
||||
struct gpio_chip *gc = &port->gc;
|
||||
struct device_node *node = pp->node;
|
||||
struct irq_chip_generic *irq_gc = NULL;
|
||||
unsigned int hwirq, ngpio = gc->ngpio;
|
||||
@@ -369,13 +363,13 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
|
||||
for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
|
||||
irq_create_mapping(gpio->domain, hwirq);
|
||||
|
||||
port->bgc.gc.to_irq = dwapb_gpio_to_irq;
|
||||
port->gc.to_irq = dwapb_gpio_to_irq;
|
||||
}
|
||||
|
||||
static void dwapb_irq_teardown(struct dwapb_gpio *gpio)
|
||||
{
|
||||
struct dwapb_gpio_port *port = &gpio->ports[0];
|
||||
struct gpio_chip *gc = &port->bgc.gc;
|
||||
struct gpio_chip *gc = &port->gc;
|
||||
unsigned int ngpio = gc->ngpio;
|
||||
irq_hw_number_t hwirq;
|
||||
|
||||
@@ -412,7 +406,7 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
|
||||
dirout = gpio->regs + GPIO_SWPORTA_DDR +
|
||||
(pp->idx * GPIO_SWPORT_DDR_SIZE);
|
||||
|
||||
err = bgpio_init(&port->bgc, gpio->dev, 4, dat, set, NULL, dirout,
|
||||
err = bgpio_init(&port->gc, gpio->dev, 4, dat, set, NULL, dirout,
|
||||
NULL, false);
|
||||
if (err) {
|
||||
dev_err(gpio->dev, "failed to init gpio chip for %s\n",
|
||||
@@ -421,19 +415,19 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_GPIO
|
||||
port->bgc.gc.of_node = pp->node;
|
||||
port->gc.of_node = pp->node;
|
||||
#endif
|
||||
port->bgc.gc.ngpio = pp->ngpio;
|
||||
port->bgc.gc.base = pp->gpio_base;
|
||||
port->gc.ngpio = pp->ngpio;
|
||||
port->gc.base = pp->gpio_base;
|
||||
|
||||
/* Only port A support debounce */
|
||||
if (pp->idx == 0)
|
||||
port->bgc.gc.set_debounce = dwapb_gpio_set_debounce;
|
||||
port->gc.set_debounce = dwapb_gpio_set_debounce;
|
||||
|
||||
if (pp->irq)
|
||||
dwapb_configure_irqs(gpio, port, pp);
|
||||
|
||||
err = gpiochip_add(&port->bgc.gc);
|
||||
err = gpiochip_add_data(&port->gc, port);
|
||||
if (err)
|
||||
dev_err(gpio->dev, "failed to register gpiochip for %s\n",
|
||||
pp->name);
|
||||
@@ -449,7 +443,7 @@ static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)
|
||||
|
||||
for (m = 0; m < gpio->nr_ports; ++m)
|
||||
if (gpio->ports[m].is_registered)
|
||||
gpiochip_remove(&gpio->ports[m].bgc.gc);
|
||||
gpiochip_remove(&gpio->ports[m].gc);
|
||||
}
|
||||
|
||||
static struct dwapb_platform_data *
|
||||
@@ -591,11 +585,11 @@ static int dwapb_gpio_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct dwapb_gpio *gpio = platform_get_drvdata(pdev);
|
||||
struct bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&bgc->lock, flags);
|
||||
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;
|
||||
@@ -624,7 +618,7 @@ static int dwapb_gpio_suspend(struct device *dev)
|
||||
dwapb_write(gpio, GPIO_INTMASK, 0xffffffff);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&bgc->lock, flags);
|
||||
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -633,11 +627,11 @@ static int dwapb_gpio_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct dwapb_gpio *gpio = platform_get_drvdata(pdev);
|
||||
struct bgpio_chip *bgc = &gpio->ports[0].bgc;
|
||||
struct gpio_chip *gc = &gpio->ports[0].gc;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&bgc->lock, flags);
|
||||
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;
|
||||
@@ -666,7 +660,7 @@ static int dwapb_gpio_resume(struct device *dev)
|
||||
dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&bgc->lock, flags);
|
||||
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user