Skip to content

Commit 033e449

Browse files
committed
Merge tag 'gpio-fixes-for-v6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio fixes from Bartosz Golaszewski: - fix a procfs failure when requesting an interrupt with a label containing the '/' character - add missing stubs for GPIO lookup functions for !GPIOLIB - fix debug messages that would print "(null)" for NULL strings * tag 'gpio-fixes-for-v6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: gpiolib: Fix debug messaging in gpiod_find_and_request() gpiolib: Add stubs for GPIO lookup functions gpio: cdev: sanitize the label before requesting the interrupt
2 parents 317c7bc + 5c887b6 commit 033e449

File tree

3 files changed

+65
-22
lines changed

3 files changed

+65
-22
lines changed

drivers/gpio/gpiolib-cdev.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,10 +1083,20 @@ static u32 gpio_v2_line_config_debounce_period(struct gpio_v2_line_config *lc,
10831083
return 0;
10841084
}
10851085

1086+
static inline char *make_irq_label(const char *orig)
1087+
{
1088+
return kstrdup_and_replace(orig, '/', ':', GFP_KERNEL);
1089+
}
1090+
1091+
static inline void free_irq_label(const char *label)
1092+
{
1093+
kfree(label);
1094+
}
1095+
10861096
static void edge_detector_stop(struct line *line)
10871097
{
10881098
if (line->irq) {
1089-
free_irq(line->irq, line);
1099+
free_irq_label(free_irq(line->irq, line));
10901100
line->irq = 0;
10911101
}
10921102

@@ -1110,6 +1120,7 @@ static int edge_detector_setup(struct line *line,
11101120
unsigned long irqflags = 0;
11111121
u64 eflags;
11121122
int irq, ret;
1123+
char *label;
11131124

11141125
eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
11151126
if (eflags && !kfifo_initialized(&line->req->events)) {
@@ -1146,11 +1157,17 @@ static int edge_detector_setup(struct line *line,
11461157
IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
11471158
irqflags |= IRQF_ONESHOT;
11481159

1160+
label = make_irq_label(line->req->label);
1161+
if (!label)
1162+
return -ENOMEM;
1163+
11491164
/* Request a thread to read the events */
11501165
ret = request_threaded_irq(irq, edge_irq_handler, edge_irq_thread,
1151-
irqflags, line->req->label, line);
1152-
if (ret)
1166+
irqflags, label, line);
1167+
if (ret) {
1168+
free_irq_label(label);
11531169
return ret;
1170+
}
11541171

11551172
line->irq = irq;
11561173
return 0;
@@ -1973,7 +1990,7 @@ static void lineevent_free(struct lineevent_state *le)
19731990
blocking_notifier_chain_unregister(&le->gdev->device_notifier,
19741991
&le->device_unregistered_nb);
19751992
if (le->irq)
1976-
free_irq(le->irq, le);
1993+
free_irq_label(free_irq(le->irq, le));
19771994
if (le->desc)
19781995
gpiod_free(le->desc);
19791996
kfree(le->label);
@@ -2114,6 +2131,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
21142131
int fd;
21152132
int ret;
21162133
int irq, irqflags = 0;
2134+
char *label;
21172135

21182136
if (copy_from_user(&eventreq, ip, sizeof(eventreq)))
21192137
return -EFAULT;
@@ -2198,15 +2216,23 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
21982216
if (ret)
21992217
goto out_free_le;
22002218

2219+
label = make_irq_label(le->label);
2220+
if (!label) {
2221+
ret = -ENOMEM;
2222+
goto out_free_le;
2223+
}
2224+
22012225
/* Request a thread to read the events */
22022226
ret = request_threaded_irq(irq,
22032227
lineevent_irq_handler,
22042228
lineevent_irq_thread,
22052229
irqflags,
2206-
le->label,
2230+
label,
22072231
le);
2208-
if (ret)
2232+
if (ret) {
2233+
free_irq_label(label);
22092234
goto out_free_le;
2235+
}
22102236

22112237
le->irq = irq;
22122238

drivers/gpio/gpiolib.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,6 +2397,11 @@ char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset)
23972397
}
23982398
EXPORT_SYMBOL_GPL(gpiochip_dup_line_label);
23992399

2400+
static inline const char *function_name_or_default(const char *con_id)
2401+
{
2402+
return con_id ?: "(default)";
2403+
}
2404+
24002405
/**
24012406
* gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor
24022407
* @gc: GPIO chip
@@ -2425,10 +2430,11 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
24252430
enum gpiod_flags dflags)
24262431
{
24272432
struct gpio_desc *desc = gpiochip_get_desc(gc, hwnum);
2433+
const char *name = function_name_or_default(label);
24282434
int ret;
24292435

24302436
if (IS_ERR(desc)) {
2431-
chip_err(gc, "failed to get GPIO descriptor\n");
2437+
chip_err(gc, "failed to get GPIO %s descriptor\n", name);
24322438
return desc;
24332439
}
24342440

@@ -2438,8 +2444,8 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
24382444

24392445
ret = gpiod_configure_flags(desc, label, lflags, dflags);
24402446
if (ret) {
2441-
chip_err(gc, "setup of own GPIO %s failed\n", label);
24422447
gpiod_free_commit(desc);
2448+
chip_err(gc, "setup of own GPIO %s failed\n", name);
24432449
return ERR_PTR(ret);
24442450
}
24452451

@@ -4153,19 +4159,17 @@ static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode,
41534159
enum gpiod_flags *flags,
41544160
unsigned long *lookupflags)
41554161
{
4162+
const char *name = function_name_or_default(con_id);
41564163
struct gpio_desc *desc = ERR_PTR(-ENOENT);
41574164

41584165
if (is_of_node(fwnode)) {
4159-
dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n",
4160-
fwnode, con_id);
4166+
dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n", fwnode, name);
41614167
desc = of_find_gpio(to_of_node(fwnode), con_id, idx, lookupflags);
41624168
} else if (is_acpi_node(fwnode)) {
4163-
dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n",
4164-
fwnode, con_id);
4169+
dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n", fwnode, name);
41654170
desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags);
41664171
} else if (is_software_node(fwnode)) {
4167-
dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n",
4168-
fwnode, con_id);
4172+
dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n", fwnode, name);
41694173
desc = swnode_find_gpio(fwnode, con_id, idx, lookupflags);
41704174
}
41714175

@@ -4181,6 +4185,7 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
41814185
bool platform_lookup_allowed)
41824186
{
41834187
unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT;
4188+
const char *name = function_name_or_default(con_id);
41844189
/*
41854190
* scoped_guard() is implemented as a for loop, meaning static
41864191
* analyzers will complain about these two not being initialized.
@@ -4203,8 +4208,7 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
42034208
}
42044209

42054210
if (IS_ERR(desc)) {
4206-
dev_dbg(consumer, "No GPIO consumer %s found\n",
4207-
con_id);
4211+
dev_dbg(consumer, "No GPIO consumer %s found\n", name);
42084212
return desc;
42094213
}
42104214

@@ -4226,15 +4230,14 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
42264230
*
42274231
* FIXME: Make this more sane and safe.
42284232
*/
4229-
dev_info(consumer,
4230-
"nonexclusive access to GPIO for %s\n", con_id);
4233+
dev_info(consumer, "nonexclusive access to GPIO for %s\n", name);
42314234
return desc;
42324235
}
42334236

42344237
ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
42354238
if (ret < 0) {
4236-
dev_dbg(consumer, "setup of GPIO %s failed\n", con_id);
42374239
gpiod_put(desc);
4240+
dev_dbg(consumer, "setup of GPIO %s failed\n", name);
42384241
return ERR_PTR(ret);
42394242
}
42404243

@@ -4350,6 +4353,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_optional);
43504353
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
43514354
unsigned long lflags, enum gpiod_flags dflags)
43524355
{
4356+
const char *name = function_name_or_default(con_id);
43534357
int ret;
43544358

43554359
if (lflags & GPIO_ACTIVE_LOW)
@@ -4393,7 +4397,7 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
43934397

43944398
/* No particular flag request, return here... */
43954399
if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
4396-
gpiod_dbg(desc, "no flags found for %s\n", con_id);
4400+
gpiod_dbg(desc, "no flags found for GPIO %s\n", name);
43974401
return 0;
43984402
}
43994403

include/linux/gpio/driver.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,6 @@ int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip *gc,
646646
struct gpio_device *gpio_device_find(const void *data,
647647
int (*match)(struct gpio_chip *gc,
648648
const void *data));
649-
struct gpio_device *gpio_device_find_by_label(const char *label);
650-
struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode);
651649

652650
struct gpio_device *gpio_device_get(struct gpio_device *gdev);
653651
void gpio_device_put(struct gpio_device *gdev);
@@ -814,6 +812,9 @@ struct gpio_device *gpiod_to_gpio_device(struct gpio_desc *desc);
814812
int gpio_device_get_base(struct gpio_device *gdev);
815813
const char *gpio_device_get_label(struct gpio_device *gdev);
816814

815+
struct gpio_device *gpio_device_find_by_label(const char *label);
816+
struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode);
817+
817818
#else /* CONFIG_GPIOLIB */
818819

819820
#include <asm/bug.h>
@@ -843,6 +844,18 @@ static inline const char *gpio_device_get_label(struct gpio_device *gdev)
843844
return NULL;
844845
}
845846

847+
static inline struct gpio_device *gpio_device_find_by_label(const char *label)
848+
{
849+
WARN_ON(1);
850+
return NULL;
851+
}
852+
853+
static inline struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode)
854+
{
855+
WARN_ON(1);
856+
return NULL;
857+
}
858+
846859
static inline int gpiochip_lock_as_irq(struct gpio_chip *gc,
847860
unsigned int offset)
848861
{

0 commit comments

Comments
 (0)