Commit 033e4491 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 317c7bc0 5c887b65
......@@ -1083,10 +1083,20 @@ static u32 gpio_v2_line_config_debounce_period(struct gpio_v2_line_config *lc,
return 0;
}
static inline char *make_irq_label(const char *orig)
{
return kstrdup_and_replace(orig, '/', ':', GFP_KERNEL);
}
static inline void free_irq_label(const char *label)
{
kfree(label);
}
static void edge_detector_stop(struct line *line)
{
if (line->irq) {
free_irq(line->irq, line);
free_irq_label(free_irq(line->irq, line));
line->irq = 0;
}
......@@ -1110,6 +1120,7 @@ static int edge_detector_setup(struct line *line,
unsigned long irqflags = 0;
u64 eflags;
int irq, ret;
char *label;
eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
if (eflags && !kfifo_initialized(&line->req->events)) {
......@@ -1146,11 +1157,17 @@ static int edge_detector_setup(struct line *line,
IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
irqflags |= IRQF_ONESHOT;
label = make_irq_label(line->req->label);
if (!label)
return -ENOMEM;
/* Request a thread to read the events */
ret = request_threaded_irq(irq, edge_irq_handler, edge_irq_thread,
irqflags, line->req->label, line);
if (ret)
irqflags, label, line);
if (ret) {
free_irq_label(label);
return ret;
}
line->irq = irq;
return 0;
......@@ -1973,7 +1990,7 @@ static void lineevent_free(struct lineevent_state *le)
blocking_notifier_chain_unregister(&le->gdev->device_notifier,
&le->device_unregistered_nb);
if (le->irq)
free_irq(le->irq, le);
free_irq_label(free_irq(le->irq, le));
if (le->desc)
gpiod_free(le->desc);
kfree(le->label);
......@@ -2114,6 +2131,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
int fd;
int ret;
int irq, irqflags = 0;
char *label;
if (copy_from_user(&eventreq, ip, sizeof(eventreq)))
return -EFAULT;
......@@ -2198,15 +2216,23 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
if (ret)
goto out_free_le;
label = make_irq_label(le->label);
if (!label) {
ret = -ENOMEM;
goto out_free_le;
}
/* Request a thread to read the events */
ret = request_threaded_irq(irq,
lineevent_irq_handler,
lineevent_irq_thread,
irqflags,
le->label,
label,
le);
if (ret)
if (ret) {
free_irq_label(label);
goto out_free_le;
}
le->irq = irq;
......
......@@ -2397,6 +2397,11 @@ char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset)
}
EXPORT_SYMBOL_GPL(gpiochip_dup_line_label);
static inline const char *function_name_or_default(const char *con_id)
{
return con_id ?: "(default)";
}
/**
* gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor
* @gc: GPIO chip
......@@ -2425,10 +2430,11 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
enum gpiod_flags dflags)
{
struct gpio_desc *desc = gpiochip_get_desc(gc, hwnum);
const char *name = function_name_or_default(label);
int ret;
if (IS_ERR(desc)) {
chip_err(gc, "failed to get GPIO descriptor\n");
chip_err(gc, "failed to get GPIO %s descriptor\n", name);
return desc;
}
......@@ -2438,8 +2444,8 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
ret = gpiod_configure_flags(desc, label, lflags, dflags);
if (ret) {
chip_err(gc, "setup of own GPIO %s failed\n", label);
gpiod_free_commit(desc);
chip_err(gc, "setup of own GPIO %s failed\n", name);
return ERR_PTR(ret);
}
......@@ -4153,19 +4159,17 @@ static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode,
enum gpiod_flags *flags,
unsigned long *lookupflags)
{
const char *name = function_name_or_default(con_id);
struct gpio_desc *desc = ERR_PTR(-ENOENT);
if (is_of_node(fwnode)) {
dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n",
fwnode, con_id);
dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n", fwnode, name);
desc = of_find_gpio(to_of_node(fwnode), con_id, idx, lookupflags);
} else if (is_acpi_node(fwnode)) {
dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n",
fwnode, con_id);
dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n", fwnode, name);
desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags);
} else if (is_software_node(fwnode)) {
dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n",
fwnode, con_id);
dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n", fwnode, name);
desc = swnode_find_gpio(fwnode, con_id, idx, lookupflags);
}
......@@ -4181,6 +4185,7 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
bool platform_lookup_allowed)
{
unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT;
const char *name = function_name_or_default(con_id);
/*
* scoped_guard() is implemented as a for loop, meaning static
* analyzers will complain about these two not being initialized.
......@@ -4203,8 +4208,7 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
}
if (IS_ERR(desc)) {
dev_dbg(consumer, "No GPIO consumer %s found\n",
con_id);
dev_dbg(consumer, "No GPIO consumer %s found\n", name);
return desc;
}
......@@ -4226,15 +4230,14 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
*
* FIXME: Make this more sane and safe.
*/
dev_info(consumer,
"nonexclusive access to GPIO for %s\n", con_id);
dev_info(consumer, "nonexclusive access to GPIO for %s\n", name);
return desc;
}
ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
if (ret < 0) {
dev_dbg(consumer, "setup of GPIO %s failed\n", con_id);
gpiod_put(desc);
dev_dbg(consumer, "setup of GPIO %s failed\n", name);
return ERR_PTR(ret);
}
......@@ -4350,6 +4353,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_optional);
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
unsigned long lflags, enum gpiod_flags dflags)
{
const char *name = function_name_or_default(con_id);
int ret;
if (lflags & GPIO_ACTIVE_LOW)
......@@ -4393,7 +4397,7 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
/* No particular flag request, return here... */
if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
gpiod_dbg(desc, "no flags found for %s\n", con_id);
gpiod_dbg(desc, "no flags found for GPIO %s\n", name);
return 0;
}
......
......@@ -646,8 +646,6 @@ int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip *gc,
struct gpio_device *gpio_device_find(const void *data,
int (*match)(struct gpio_chip *gc,
const void *data));
struct gpio_device *gpio_device_find_by_label(const char *label);
struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode);
struct gpio_device *gpio_device_get(struct gpio_device *gdev);
void gpio_device_put(struct gpio_device *gdev);
......@@ -814,6 +812,9 @@ struct gpio_device *gpiod_to_gpio_device(struct gpio_desc *desc);
int gpio_device_get_base(struct gpio_device *gdev);
const char *gpio_device_get_label(struct gpio_device *gdev);
struct gpio_device *gpio_device_find_by_label(const char *label);
struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode);
#else /* CONFIG_GPIOLIB */
#include <asm/bug.h>
......@@ -843,6 +844,18 @@ static inline const char *gpio_device_get_label(struct gpio_device *gdev)
return NULL;
}
static inline struct gpio_device *gpio_device_find_by_label(const char *label)
{
WARN_ON(1);
return NULL;
}
static inline struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode)
{
WARN_ON(1);
return NULL;
}
static inline int gpiochip_lock_as_irq(struct gpio_chip *gc,
unsigned int offset)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment