Commit 0b9df436 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gpio-fixes-for-v5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:

 - use sleeping variants of GPIO accessors where needed
   in gpio-aggregator

 - never return kernel's internal error codes to user-space
   in gpiolib core

 - use the correct register for reading output values in
   gpio-sifive

 - fix line hogging in gpio-sim

* tag 'gpio-fixes-for-v5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpio: sim: fix hogs with custom chip labels
  gpio: sifive: use the correct register to read output values
  gpiolib: Never return internal error codes to user space
  gpio: aggregator: Fix calling into sleeping GPIO controllers
parents 284fce04 c162ca0b
...@@ -278,7 +278,8 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset) ...@@ -278,7 +278,8 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset)
{ {
struct gpiochip_fwd *fwd = gpiochip_get_data(chip); struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
return gpiod_get_value(fwd->descs[offset]); return chip->can_sleep ? gpiod_get_value_cansleep(fwd->descs[offset])
: gpiod_get_value(fwd->descs[offset]);
} }
static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
...@@ -293,6 +294,9 @@ static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, ...@@ -293,6 +294,9 @@ static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
for_each_set_bit(i, mask, fwd->chip.ngpio) for_each_set_bit(i, mask, fwd->chip.ngpio)
descs[j++] = fwd->descs[i]; descs[j++] = fwd->descs[i];
if (fwd->chip.can_sleep)
error = gpiod_get_array_value_cansleep(j, descs, NULL, values);
else
error = gpiod_get_array_value(j, descs, NULL, values); error = gpiod_get_array_value(j, descs, NULL, values);
if (error) if (error)
return error; return error;
...@@ -328,6 +332,9 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value) ...@@ -328,6 +332,9 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value)
{ {
struct gpiochip_fwd *fwd = gpiochip_get_data(chip); struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
if (chip->can_sleep)
gpiod_set_value_cansleep(fwd->descs[offset], value);
else
gpiod_set_value(fwd->descs[offset], value); gpiod_set_value(fwd->descs[offset], value);
} }
...@@ -343,6 +350,9 @@ static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, ...@@ -343,6 +350,9 @@ static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
descs[j++] = fwd->descs[i]; descs[j++] = fwd->descs[i];
} }
if (fwd->chip.can_sleep)
gpiod_set_array_value_cansleep(j, descs, NULL, values);
else
gpiod_set_array_value(j, descs, NULL, values); gpiod_set_array_value(j, descs, NULL, values);
} }
......
...@@ -223,7 +223,7 @@ static int sifive_gpio_probe(struct platform_device *pdev) ...@@ -223,7 +223,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
NULL, NULL,
chip->base + SIFIVE_GPIO_OUTPUT_EN, chip->base + SIFIVE_GPIO_OUTPUT_EN,
chip->base + SIFIVE_GPIO_INPUT_EN, chip->base + SIFIVE_GPIO_INPUT_EN,
0); BGPIOF_READ_OUTPUT_REG_SET);
if (ret) { if (ret) {
dev_err(dev, "unable to init generic GPIO\n"); dev_err(dev, "unable to init generic GPIO\n");
return ret; return ret;
......
...@@ -570,6 +570,11 @@ static struct gpio_sim_bank *to_gpio_sim_bank(struct config_item *item) ...@@ -570,6 +570,11 @@ static struct gpio_sim_bank *to_gpio_sim_bank(struct config_item *item)
return container_of(group, struct gpio_sim_bank, group); return container_of(group, struct gpio_sim_bank, group);
} }
static bool gpio_sim_bank_has_label(struct gpio_sim_bank *bank)
{
return bank->label && *bank->label;
}
static struct gpio_sim_device * static struct gpio_sim_device *
gpio_sim_bank_get_device(struct gpio_sim_bank *bank) gpio_sim_bank_get_device(struct gpio_sim_bank *bank)
{ {
...@@ -770,9 +775,15 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev) ...@@ -770,9 +775,15 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev)
* point the device doesn't exist yet and so dev_name() * point the device doesn't exist yet and so dev_name()
* is not available. * is not available.
*/ */
if (gpio_sim_bank_has_label(bank))
hog->chip_label = kstrdup(bank->label,
GFP_KERNEL);
else
hog->chip_label = kasprintf(GFP_KERNEL, hog->chip_label = kasprintf(GFP_KERNEL,
"gpio-sim.%u-%s", dev->id, "gpio-sim.%u-%s",
fwnode_get_name(bank->swnode)); dev->id,
fwnode_get_name(
bank->swnode));
if (!hog->chip_label) { if (!hog->chip_label) {
gpio_sim_remove_hogs(dev); gpio_sim_remove_hogs(dev);
return -ENOMEM; return -ENOMEM;
...@@ -816,7 +827,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, ...@@ -816,7 +827,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank,
properties[prop_idx++] = PROPERTY_ENTRY_U32("ngpios", bank->num_lines); properties[prop_idx++] = PROPERTY_ENTRY_U32("ngpios", bank->num_lines);
if (bank->label && (strlen(bank->label) > 0)) if (gpio_sim_bank_has_label(bank))
properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label", properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label",
bank->label); bank->label);
......
...@@ -330,7 +330,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ...@@ -330,7 +330,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
goto out_free_lh; goto out_free_lh;
} }
ret = gpiod_request(desc, lh->label); ret = gpiod_request_user(desc, lh->label);
if (ret) if (ret)
goto out_free_lh; goto out_free_lh;
lh->descs[i] = desc; lh->descs[i] = desc;
...@@ -1378,7 +1378,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip) ...@@ -1378,7 +1378,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip)
goto out_free_linereq; goto out_free_linereq;
} }
ret = gpiod_request(desc, lr->label); ret = gpiod_request_user(desc, lr->label);
if (ret) if (ret)
goto out_free_linereq; goto out_free_linereq;
...@@ -1764,7 +1764,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) ...@@ -1764,7 +1764,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
} }
} }
ret = gpiod_request(desc, le->label); ret = gpiod_request_user(desc, le->label);
if (ret) if (ret)
goto out_free_le; goto out_free_le;
le->desc = desc; le->desc = desc;
......
...@@ -475,12 +475,9 @@ static ssize_t export_store(struct class *class, ...@@ -475,12 +475,9 @@ static ssize_t export_store(struct class *class,
* they may be undone on its behalf too. * they may be undone on its behalf too.
*/ */
status = gpiod_request(desc, "sysfs"); status = gpiod_request_user(desc, "sysfs");
if (status) { if (status)
if (status == -EPROBE_DEFER)
status = -ENODEV;
goto done; goto done;
}
status = gpiod_set_transitory(desc, false); status = gpiod_set_transitory(desc, false);
if (!status) { if (!status) {
......
...@@ -135,6 +135,18 @@ struct gpio_desc { ...@@ -135,6 +135,18 @@ struct gpio_desc {
int gpiod_request(struct gpio_desc *desc, const char *label); int gpiod_request(struct gpio_desc *desc, const char *label);
void gpiod_free(struct gpio_desc *desc); void gpiod_free(struct gpio_desc *desc);
static inline int gpiod_request_user(struct gpio_desc *desc, const char *label)
{
int ret;
ret = gpiod_request(desc, label);
if (ret == -EPROBE_DEFER)
ret = -ENODEV;
return ret;
}
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
unsigned long lflags, enum gpiod_flags dflags); unsigned long lflags, enum gpiod_flags dflags);
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce); int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
......
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