Skip to content

Commit 78b778e

Browse files
committed
Merge tag 'gpio-remove-gpiochip_is_requested-for-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel
gpio: remove gpiochip_is_requested() - provide a safer alternative to gpiochip_is_requested() - convert all existing users - remove gpiochip_is_requested()
2 parents 583b527 + f8d05e2 commit 78b778e

File tree

9 files changed

+96
-47
lines changed

9 files changed

+96
-47
lines changed

drivers/gpio/gpio-stmpe.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Author: Rabin Vincent <[email protected]> for ST-Ericsson
66
*/
77

8+
#include <linux/cleanup.h>
89
#include <linux/init.h>
910
#include <linux/platform_device.h>
1011
#include <linux/slab.h>
@@ -255,14 +256,17 @@ static void stmpe_dbg_show_one(struct seq_file *s,
255256
{
256257
struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc);
257258
struct stmpe *stmpe = stmpe_gpio->stmpe;
258-
const char *label = gpiochip_is_requested(gc, offset);
259259
bool val = !!stmpe_gpio_get(gc, offset);
260260
u8 bank = offset / 8;
261261
u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB + bank];
262262
u8 mask = BIT(offset % 8);
263263
int ret;
264264
u8 dir;
265265

266+
char *label __free(kfree) = gpiochip_dup_line_label(gc, offset);
267+
if (IS_ERR(label))
268+
return;
269+
266270
ret = stmpe_reg_read(stmpe, dir_reg);
267271
if (ret < 0)
268272
return;

drivers/gpio/gpio-wm831x.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*
99
*/
1010

11+
#include <linux/cleanup.h>
1112
#include <linux/kernel.h>
1213
#include <linux/slab.h>
1314
#include <linux/module.h>
@@ -160,18 +161,21 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
160161
for (i = 0; i < chip->ngpio; i++) {
161162
int gpio = i + chip->base;
162163
int reg;
163-
const char *label, *pull, *powerdomain;
164+
const char *pull, *powerdomain;
164165

165166
/* We report the GPIO even if it's not requested since
166167
* we're also reporting things like alternate
167168
* functions which apply even when the GPIO is not in
168169
* use as a GPIO.
169170
*/
170-
label = gpiochip_is_requested(chip, i);
171-
if (!label)
172-
label = "Unrequested";
171+
char *label __free(kfree) = gpiochip_dup_line_label(chip, i);
172+
if (IS_ERR(label)) {
173+
dev_err(wm831x->dev, "Failed to duplicate label\n");
174+
continue;
175+
}
173176

174-
seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label);
177+
seq_printf(s, " gpio-%-3d (%-20.20s) ",
178+
gpio, label ?: "Unrequested");
175179

176180
reg = wm831x_reg_read(wm831x, WM831X_GPIO1_CONTROL + i);
177181
if (reg < 0) {

drivers/gpio/gpio-wm8994.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*
99
*/
1010

11+
#include <linux/cleanup.h>
1112
#include <linux/kernel.h>
1213
#include <linux/slab.h>
1314
#include <linux/module.h>
@@ -193,18 +194,20 @@ static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
193194
for (i = 0; i < chip->ngpio; i++) {
194195
int gpio = i + chip->base;
195196
int reg;
196-
const char *label;
197197

198198
/* We report the GPIO even if it's not requested since
199199
* we're also reporting things like alternate
200200
* functions which apply even when the GPIO is not in
201201
* use as a GPIO.
202202
*/
203-
label = gpiochip_is_requested(chip, i);
204-
if (!label)
205-
label = "Unrequested";
203+
char *label __free(kfree) = gpiochip_dup_line_label(chip, i);
204+
if (IS_ERR(label)) {
205+
dev_err(wm8994->dev, "Failed to duplicate label\n");
206+
continue;
207+
}
206208

207-
seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label);
209+
seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio,
210+
label ?: "Unrequested");
208211

209212
reg = wm8994_reg_read(wm8994, WM8994_GPIO_1 + i);
210213
if (reg < 0) {

drivers/gpio/gpiolib.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,7 @@ void gpiochip_remove(struct gpio_chip *gc)
10851085

10861086
spin_lock_irqsave(&gpio_lock, flags);
10871087
for (i = 0; i < gdev->ngpio; i++) {
1088-
if (gpiochip_is_requested(gc, i))
1088+
if (test_bit(FLAG_REQUESTED, &gdev->descs[i].flags))
10891089
break;
10901090
}
10911091
spin_unlock_irqrestore(&gpio_lock, flags);
@@ -2374,31 +2374,38 @@ void gpiod_free(struct gpio_desc *desc)
23742374
}
23752375

23762376
/**
2377-
* gpiochip_is_requested - return string iff signal was requested
2378-
* @gc: controller managing the signal
2379-
* @offset: of signal within controller's 0..(ngpio - 1) range
2377+
* gpiochip_dup_line_label - Get a copy of the consumer label.
2378+
* @gc: GPIO chip controlling this line.
2379+
* @offset: Hardware offset of the line.
23802380
*
2381-
* Returns NULL if the GPIO is not currently requested, else a string.
2382-
* The string returned is the label passed to gpio_request(); if none has been
2383-
* passed it is a meaningless, non-NULL constant.
2381+
* Returns:
2382+
* Pointer to a copy of the consumer label if the line is requested or NULL
2383+
* if it's not. If a valid pointer was returned, it must be freed using
2384+
* kfree(). In case of a memory allocation error, the function returns %ENOMEM.
23842385
*
2385-
* This function is for use by GPIO controller drivers. The label can
2386-
* help with diagnostics, and knowing that the signal is used as a GPIO
2387-
* can help avoid accidentally multiplexing it to another controller.
2386+
* Must not be called from atomic context.
23882387
*/
2389-
const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned int offset)
2388+
char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset)
23902389
{
23912390
struct gpio_desc *desc;
2391+
char *label;
23922392

23932393
desc = gpiochip_get_desc(gc, offset);
23942394
if (IS_ERR(desc))
23952395
return NULL;
23962396

2397-
if (test_bit(FLAG_REQUESTED, &desc->flags) == 0)
2397+
guard(spinlock_irqsave)(&gpio_lock);
2398+
2399+
if (!test_bit(FLAG_REQUESTED, &desc->flags))
23982400
return NULL;
2399-
return desc->label;
2401+
2402+
label = kstrdup(desc->label, GFP_KERNEL);
2403+
if (!label)
2404+
return ERR_PTR(-ENOMEM);
2405+
2406+
return label;
24002407
}
2401-
EXPORT_SYMBOL_GPL(gpiochip_is_requested);
2408+
EXPORT_SYMBOL_GPL(gpiochip_dup_line_label);
24022409

24032410
/**
24042411
* gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor

drivers/pinctrl/intel/pinctrl-baytrail.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/acpi.h>
1010
#include <linux/array_size.h>
1111
#include <linux/bitops.h>
12+
#include <linux/cleanup.h>
1213
#include <linux/gpio/driver.h>
1314
#include <linux/init.h>
1415
#include <linux/interrupt.h>
@@ -1173,7 +1174,6 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
11731174
const char *pull_str = NULL;
11741175
const char *pull = NULL;
11751176
unsigned long flags;
1176-
const char *label;
11771177
unsigned int pin;
11781178

11791179
pin = vg->soc->pins[i].number;
@@ -1200,9 +1200,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
12001200
seq_printf(s, "Pin %i: can't retrieve community\n", pin);
12011201
continue;
12021202
}
1203-
label = gpiochip_is_requested(chip, i);
1204-
if (!label)
1205-
label = "Unrequested";
1203+
1204+
char *label __free(kfree) = gpiochip_dup_line_label(chip, i);
1205+
if (IS_ERR(label))
1206+
continue;
12061207

12071208
switch (conf0 & BYT_PULL_ASSIGN_MASK) {
12081209
case BYT_PULL_ASSIGN_UP:
@@ -1231,7 +1232,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
12311232
seq_printf(s,
12321233
" gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
12331234
pin,
1234-
label,
1235+
label ?: "Unrequested",
12351236
val & BYT_INPUT_EN ? " " : "in",
12361237
val & BYT_OUTPUT_EN ? " " : "out",
12371238
str_hi_lo(val & BYT_LEVEL),

drivers/pinctrl/nomadik/pinctrl-abx500.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
*
77
* Driver allows to use AxB5xx unused pins to be used as GPIO
88
*/
9+
910
#include <linux/bitops.h>
11+
#include <linux/cleanup.h>
1012
#include <linux/err.h>
1113
#include <linux/gpio/driver.h>
1214
#include <linux/init.h>
@@ -453,12 +455,11 @@ static void abx500_gpio_dbg_show_one(struct seq_file *s,
453455
unsigned offset, unsigned gpio)
454456
{
455457
struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
456-
const char *label = gpiochip_is_requested(chip, offset - 1);
457458
u8 gpio_offset = offset - 1;
458459
int mode = -1;
459460
bool is_out;
460461
bool pd;
461-
int ret;
462+
int ret = -ENOMEM;
462463

463464
const char *modes[] = {
464465
[ABX500_DEFAULT] = "default",
@@ -474,6 +475,10 @@ static void abx500_gpio_dbg_show_one(struct seq_file *s,
474475
[ABX500_GPIO_PULL_UP] = "pull up",
475476
};
476477

478+
char *label __free(kfree) = gpiochip_dup_line_label(chip, offset - 1);
479+
if (IS_ERR(label))
480+
goto out;
481+
477482
ret = abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG,
478483
gpio_offset, &is_out);
479484
if (ret < 0)

drivers/pinctrl/nomadik/pinctrl-nomadik.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Copyright (C) 2011-2013 Linus Walleij <[email protected]>
99
*/
1010
#include <linux/bitops.h>
11+
#include <linux/cleanup.h>
1112
#include <linux/clk.h>
1213
#include <linux/device.h>
1314
#include <linux/err.h>
@@ -917,7 +918,6 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
917918
struct pinctrl_dev *pctldev, struct gpio_chip *chip,
918919
unsigned offset, unsigned gpio)
919920
{
920-
const char *label = gpiochip_is_requested(chip, offset);
921921
struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
922922
int mode;
923923
bool is_out;
@@ -934,6 +934,10 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
934934
[NMK_GPIO_ALT_C+4] = "altC4",
935935
};
936936

937+
char *label = gpiochip_dup_line_label(chip, offset);
938+
if (IS_ERR(label))
939+
return;
940+
937941
clk_enable(nmk_chip->clk);
938942
is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
939943
pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset));

drivers/pinctrl/sunplus/sppctl.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (C) Sunplus Tech / Tibbo Tech.
55
*/
66

7+
#include <linux/cleanup.h>
78
#include <linux/bitfield.h>
89
#include <linux/device.h>
910
#include <linux/err.h>
@@ -500,16 +501,15 @@ static int sppctl_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
500501

501502
static void sppctl_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
502503
{
503-
const char *label;
504504
int i;
505505

506506
for (i = 0; i < chip->ngpio; i++) {
507-
label = gpiochip_is_requested(chip, i);
508-
if (!label)
509-
label = "";
507+
char *label __free(kfree) = gpiochip_dup_line_label(chip, i);
508+
if (IS_ERR(label))
509+
continue;
510510

511511
seq_printf(s, " gpio-%03d (%-16.16s | %-16.16s)", i + chip->base,
512-
chip->names[i], label);
512+
chip->names[i], label ?: "");
513513
seq_printf(s, " %c", sppctl_gpio_get_direction(chip, i) ? 'I' : 'O');
514514
seq_printf(s, ":%d", sppctl_gpio_get(chip, i));
515515
seq_printf(s, " %s", sppctl_first_get(chip, i) ? "gpi" : "mux");

include/linux/gpio/driver.h

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -531,19 +531,40 @@ struct gpio_chip {
531531
#endif /* CONFIG_OF_GPIO */
532532
};
533533

534-
const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned int offset);
534+
char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset);
535+
536+
537+
struct _gpiochip_for_each_data {
538+
const char **label;
539+
unsigned int *i;
540+
};
541+
542+
DEFINE_CLASS(_gpiochip_for_each_data,
543+
struct _gpiochip_for_each_data,
544+
if (*_T.label) kfree(*_T.label),
545+
({
546+
struct _gpiochip_for_each_data _data = { label, i };
547+
*_data.i = 0;
548+
_data;
549+
}),
550+
const char **label, int *i)
535551

536552
/**
537553
* for_each_requested_gpio_in_range - iterates over requested GPIOs in a given range
538-
* @chip: the chip to query
539-
* @i: loop variable
540-
* @base: first GPIO in the range
541-
* @size: amount of GPIOs to check starting from @base
542-
* @label: label of current GPIO
554+
* @_chip: the chip to query
555+
* @_i: loop variable
556+
* @_base: first GPIO in the range
557+
* @_size: amount of GPIOs to check starting from @base
558+
* @_label: label of current GPIO
543559
*/
544-
#define for_each_requested_gpio_in_range(chip, i, base, size, label) \
545-
for (i = 0; i < size; i++) \
546-
if ((label = gpiochip_is_requested(chip, base + i)) == NULL) {} else
560+
#define for_each_requested_gpio_in_range(_chip, _i, _base, _size, _label) \
561+
for (CLASS(_gpiochip_for_each_data, _data)(&_label, &_i); \
562+
*_data.i < _size; \
563+
(*_data.i)++, kfree(*(_data.label)), *_data.label = NULL) \
564+
if ((*_data.label = \
565+
gpiochip_dup_line_label(_chip, _base + *_data.i)) == NULL) {} \
566+
else if (IS_ERR(*_data.label)) {} \
567+
else
547568

548569
/* Iterates over all requested GPIO of the given @chip */
549570
#define for_each_requested_gpio(chip, i, label) \

0 commit comments

Comments
 (0)