Skip to content

Commit 2251fbd

Browse files
tq-schiffermBartosz Golaszewski
authored andcommitted
gpio: tqmx86: add support for changing GPIO directions
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>
1 parent a1389f5 commit 2251fbd

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

drivers/gpio/gpio-tqmx86.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,46 +85,62 @@ static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)
8585
return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));
8686
}
8787

88+
static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset,
89+
int value)
90+
__must_hold(&gpio->spinlock)
91+
{
92+
__assign_bit(offset, gpio->output, value);
93+
tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
94+
}
95+
8896
static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
8997
int value)
9098
{
9199
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
92100

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

95-
__assign_bit(offset, gpio->output, value);
96-
tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
103+
_tqmx86_gpio_set(gpio, offset, value);
97104
}
98105

99106
static int tqmx86_gpio_direction_input(struct gpio_chip *chip,
100107
unsigned int offset)
101108
{
102-
/* Direction cannot be changed. Validate is an input. */
103-
if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
104-
return 0;
105-
else
106-
return -EINVAL;
109+
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
110+
111+
guard(raw_spinlock_irqsave)(&gpio->spinlock);
112+
113+
tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD);
114+
115+
return 0;
107116
}
108117

109118
static int tqmx86_gpio_direction_output(struct gpio_chip *chip,
110119
unsigned int offset,
111120
int value)
112121
{
113-
/* Direction cannot be changed, validate is an output */
114-
if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
115-
return -EINVAL;
122+
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
123+
124+
guard(raw_spinlock_irqsave)(&gpio->spinlock);
125+
126+
_tqmx86_gpio_set(gpio, offset, value);
127+
tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD);
116128

117-
tqmx86_gpio_set(chip, offset, value);
118129
return 0;
119130
}
120131

121132
static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
122133
unsigned int offset)
123134
{
124-
if (TQMX86_DIR_INPUT_MASK & BIT(offset))
125-
return GPIO_LINE_DIRECTION_IN;
135+
struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
136+
u8 val;
137+
138+
val = tqmx86_gpio_read(gpio, TQMX86_GPIODD);
139+
140+
if (val & BIT(offset))
141+
return GPIO_LINE_DIRECTION_OUT;
126142

127-
return GPIO_LINE_DIRECTION_OUT;
143+
return GPIO_LINE_DIRECTION_IN;
128144
}
129145

130146
static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq)

0 commit comments

Comments
 (0)