Skip to content

Commit 1cf0668

Browse files
committed
Merge tag 'gpio-fixes-for-v6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio fixes from Bartosz Golaszewski: "An assortment of driver fixes and two commits addressing a bad behavior of the GPIO uAPI when reconfiguring requested lines. - fix a race condition in i2c transfers by adding a missing i2c lock section in gpio-pca953x - validate the number of obtained interrupts in gpio-davinci - add missing raw_spinlock_init() in gpio-graniterapids - fix bad character device behavior: disallow GPIO line reconfiguration without set direction both in v1 and v2 uAPI" * tag 'gpio-fixes-for-v6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: gpiolib: cdev: Ignore reconfiguration without direction gpiolib: cdev: Disallow reconfiguration without direction (uAPI v1) gpio: graniterapids: Add missing raw_spinlock_init() gpio: davinci: Validate the obtained number of IRQs gpio: pca953x: fix pca953x_irq_bus_sync_unlock race
2 parents 9038455 + b440396 commit 1cf0668

File tree

4 files changed

+26
-11
lines changed

4 files changed

+26
-11
lines changed

drivers/gpio/gpio-davinci.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ static int davinci_gpio_probe(struct platform_device *pdev)
225225
else
226226
nirq = DIV_ROUND_UP(ngpio, 16);
227227

228+
if (nirq > MAX_INT_PER_BANK) {
229+
dev_err(dev, "Too many IRQs!\n");
230+
return -EINVAL;
231+
}
232+
228233
chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL);
229234
if (!chips)
230235
return -ENOMEM;

drivers/gpio/gpio-graniterapids.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ static int gnr_gpio_probe(struct platform_device *pdev)
296296
if (!priv)
297297
return -ENOMEM;
298298

299+
raw_spin_lock_init(&priv->lock);
300+
299301
regs = devm_platform_ioremap_resource(pdev, 0);
300302
if (IS_ERR(regs))
301303
return PTR_ERR(regs);

drivers/gpio/gpio-pca953x.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
758758
int level;
759759

760760
if (chip->driver_data & PCA_PCAL) {
761+
guard(mutex)(&chip->i2c_lock);
762+
761763
/* Enable latch on interrupt-enabled inputs */
762764
pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask);
763765

drivers/gpio/gpiolib-cdev.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ struct linehandle_state {
8989
GPIOHANDLE_REQUEST_OPEN_DRAIN | \
9090
GPIOHANDLE_REQUEST_OPEN_SOURCE)
9191

92+
#define GPIOHANDLE_REQUEST_DIRECTION_FLAGS \
93+
(GPIOHANDLE_REQUEST_INPUT | \
94+
GPIOHANDLE_REQUEST_OUTPUT)
95+
9296
static int linehandle_validate_flags(u32 flags)
9397
{
9498
/* Return an error if an unknown flag is set */
@@ -169,21 +173,21 @@ static long linehandle_set_config(struct linehandle_state *lh,
169173
if (ret)
170174
return ret;
171175

176+
/* Lines must be reconfigured explicitly as input or output. */
177+
if (!(lflags & GPIOHANDLE_REQUEST_DIRECTION_FLAGS))
178+
return -EINVAL;
179+
172180
for (i = 0; i < lh->num_descs; i++) {
173181
desc = lh->descs[i];
174-
linehandle_flags_to_desc_flags(gcnf.flags, &desc->flags);
182+
linehandle_flags_to_desc_flags(lflags, &desc->flags);
175183

176-
/*
177-
* Lines have to be requested explicitly for input
178-
* or output, else the line will be treated "as is".
179-
*/
180184
if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
181185
int val = !!gcnf.default_values[i];
182186

183187
ret = gpiod_direction_output(desc, val);
184188
if (ret)
185189
return ret;
186-
} else if (lflags & GPIOHANDLE_REQUEST_INPUT) {
190+
} else {
187191
ret = gpiod_direction_input(desc);
188192
if (ret)
189193
return ret;
@@ -1530,20 +1534,22 @@ static long linereq_set_config(struct linereq *lr, void __user *ip)
15301534
line = &lr->lines[i];
15311535
desc = lr->lines[i].desc;
15321536
flags = gpio_v2_line_config_flags(&lc, i);
1533-
gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
1534-
edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS;
15351537
/*
1536-
* Lines have to be requested explicitly for input
1537-
* or output, else the line will be treated "as is".
1538+
* Lines not explicitly reconfigured as input or output
1539+
* are left unchanged.
15381540
*/
1541+
if (!(flags & GPIO_V2_LINE_DIRECTION_FLAGS))
1542+
continue;
1543+
gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
1544+
edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS;
15391545
if (flags & GPIO_V2_LINE_FLAG_OUTPUT) {
15401546
int val = gpio_v2_line_config_output_value(&lc, i);
15411547

15421548
edge_detector_stop(line);
15431549
ret = gpiod_direction_output(desc, val);
15441550
if (ret)
15451551
return ret;
1546-
} else if (flags & GPIO_V2_LINE_FLAG_INPUT) {
1552+
} else {
15471553
ret = gpiod_direction_input(desc);
15481554
if (ret)
15491555
return ret;

0 commit comments

Comments
 (0)