Message ID | 0fd4b472b1ed6d67d8d1fe2f20d3bedd7eda210f.1733739697.git.matthias.schiffer@ew.tq-group.com |
---|---|
State | Superseded |
Headers | show |
Series | gpio-tqmx86: cleanup + changing directions | expand |
On Mon, Dec 9, 2024 at 11:36 AM Matthias Schiffer <matthias.schiffer@ew.tq-group.com> wrote: > > Only GPIOs 4..7 have IRQ support on the TQMx86 variants currently handled > by the driver, but apart from that, changing directions works fine. The > default directions are left unchanged (0..3 output, 4..7 input) to match > the COM Express specification. > > A tqmx86_gpio_set() variant without locking is introduced as a new > helper. > > Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com> > --- > drivers/gpio/gpio-tqmx86.c | 46 ++++++++++++++++++++++++++------------ > 1 file changed, 32 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c > index 54e7e193bb209..4c7e7b5950426 100644 > --- a/drivers/gpio/gpio-tqmx86.c > +++ b/drivers/gpio/gpio-tqmx86.c > @@ -84,6 +84,14 @@ static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset) > return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset)); > } > > +static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset, > + int value) > + __must_hold(&gpio->spinlock) > +{ > + __assign_bit(offset, gpio->output, value); > + tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); > +} > + > static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset, > int value) > { > @@ -91,40 +99,50 @@ static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset, > unsigned long flags; > > raw_spin_lock_irqsave(&gpio->spinlock, flags); > - __assign_bit(offset, gpio->output, value); > - tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); > + _tqmx86_gpio_set(gpio, offset, value); > raw_spin_unlock_irqrestore(&gpio->spinlock, flags); > } > > static int tqmx86_gpio_direction_input(struct gpio_chip *chip, > unsigned int offset) > { > - /* Direction cannot be changed. Validate is an input. */ > - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) > - return 0; > - else > - return -EINVAL; > + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); > + unsigned long flags; > + > + raw_spin_lock_irqsave(&gpio->spinlock, flags); > + tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD); > + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); Maybe switch to using lock guards if you're changing the code anyway? Bart > + > + return 0; > } > > static int tqmx86_gpio_direction_output(struct gpio_chip *chip, > unsigned int offset, > int value) > { > - /* Direction cannot be changed, validate is an output */ > - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) > - return -EINVAL; > + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); > + unsigned long flags; > + > + raw_spin_lock_irqsave(&gpio->spinlock, flags); > + _tqmx86_gpio_set(gpio, offset, value); > + tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD); > + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); > > - tqmx86_gpio_set(chip, offset, value); > return 0; > } > > static int tqmx86_gpio_get_direction(struct gpio_chip *chip, > unsigned int offset) > { > - if (TQMX86_DIR_INPUT_MASK & BIT(offset)) > - return GPIO_LINE_DIRECTION_IN; > + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); > + u8 val; > + > + val = tqmx86_gpio_read(gpio, TQMX86_GPIODD); > + > + if (val & BIT(offset)) > + return GPIO_LINE_DIRECTION_OUT; > > - return GPIO_LINE_DIRECTION_OUT; > + return GPIO_LINE_DIRECTION_IN; > } > > static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq) > -- > TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany > Amtsgericht München, HRB 105018 > Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider > https://www.tq-group.com/ >
diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c index 54e7e193bb209..4c7e7b5950426 100644 --- a/drivers/gpio/gpio-tqmx86.c +++ b/drivers/gpio/gpio-tqmx86.c @@ -84,6 +84,14 @@ static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset) return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset)); } +static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset, + int value) + __must_hold(&gpio->spinlock) +{ + __assign_bit(offset, gpio->output, value); + tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); +} + static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { @@ -91,40 +99,50 @@ static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset, unsigned long flags; raw_spin_lock_irqsave(&gpio->spinlock, flags); - __assign_bit(offset, gpio->output, value); - tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); + _tqmx86_gpio_set(gpio, offset, value); raw_spin_unlock_irqrestore(&gpio->spinlock, flags); } static int tqmx86_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - /* Direction cannot be changed. Validate is an input. */ - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) - return 0; - else - return -EINVAL; + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); + unsigned long flags; + + raw_spin_lock_irqsave(&gpio->spinlock, flags); + tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD); + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + + return 0; } static int tqmx86_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - /* Direction cannot be changed, validate is an output */ - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) - return -EINVAL; + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); + unsigned long flags; + + raw_spin_lock_irqsave(&gpio->spinlock, flags); + _tqmx86_gpio_set(gpio, offset, value); + tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD); + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); - tqmx86_gpio_set(chip, offset, value); return 0; } static int tqmx86_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - if (TQMX86_DIR_INPUT_MASK & BIT(offset)) - return GPIO_LINE_DIRECTION_IN; + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); + u8 val; + + val = tqmx86_gpio_read(gpio, TQMX86_GPIODD); + + if (val & BIT(offset)) + return GPIO_LINE_DIRECTION_OUT; - return GPIO_LINE_DIRECTION_OUT; + return GPIO_LINE_DIRECTION_IN; } static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq)
Only GPIOs 4..7 have IRQ support on the TQMx86 variants currently handled by the driver, but apart from that, changing directions works fine. The default directions are left unchanged (0..3 output, 4..7 input) to match the COM Express specification. A tqmx86_gpio_set() variant without locking is introduced as a new helper. Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com> --- drivers/gpio/gpio-tqmx86.c | 46 ++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 14 deletions(-)