Skip to content

Commit

Permalink
gpio: tqmx86: add support for changing GPIO directions
Browse files Browse the repository at this point in the history
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>
Link: https://lore.kernel.org/r/d89da2f0e13fa6c8ec3f9076eed242133a1e3a63.1734001247.git.matthias.schiffer@ew.tq-group.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
  • Loading branch information
Matthias Schiffer authored and Bartosz Golaszewski committed Dec 16, 2024
1 parent a1389f5 commit 2251fbd
Showing 1 changed file with 30 additions and 14 deletions.
44 changes: 30 additions & 14 deletions drivers/gpio/gpio-tqmx86.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,46 +85,62 @@ 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)
{
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);

guard(raw_spinlock_irqsave)(&gpio->spinlock);

__assign_bit(offset, gpio->output, value);
tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
_tqmx86_gpio_set(gpio, offset, value);
}

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);

guard(raw_spinlock_irqsave)(&gpio->spinlock);

tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD);

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);

guard(raw_spinlock_irqsave)(&gpio->spinlock);

_tqmx86_gpio_set(gpio, offset, value);
tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD);

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)
Expand Down

0 comments on commit 2251fbd

Please sign in to comment.