gpio fixes for v5.17-rc4
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAmIGXv8ACgkQEacuoBRx 13IAhg//UUlwiJJ+DS+B3ZNFGjgEu7bXD8E323SVz4BczCksG0dFOMzwMko9rUc8 dm6w1ICErY/QBdJfW25iplEBvY9d2lr0gl1zQfsraAHWk1dK4GjxJo0sTmjs3kl6 EwVMvWO+AL0uzvVUC60Z2TuuUqQsCeyIaIz51obw9yVqWDGzQUqQpfKI9kTSEGEq bX4SqguaF0a7FIukUIHS8cfJEt6eGs9XRyhKbj2YktQQJQSSYvHvGdx8iAgNjk0X hHBlqoSeK3BRKNKy87bHuYgL8SDW2SyCjsm/WbYY7bjJiv0SRMBVAd3mukiYmPrA SGEpuNLaRNYNG77mtRK8NT4aVIb2O714HYIV4/pJ8Id9cVbJEyjNnLJbq9Its+T7 fOqjdcXTR59dyjyeVzjj4L35TvgfyaRL5DaPhxsYY65ASR1G+5xmiAhtSSu3lBsL 5mSq3zJ2PUReioLpnRaPxwYB/KFdOEubL3lqsh4E8YaijgVM1Z9FcsAov7unaRi+ PsFSx4gfoD4SynavcbE4Bn0TjO/zRR2c38A341M94E75T4ss0BxHAS0JqhIeEjP1 NbMia5PVkhZBboOkbFiELqJUG9GOibKsEXO+qw0YbHsAUBcsfqDIMVnDZEGfqJC5 V8bySmwGB5TnH7dfRhl8/83cA5Cf1Yy6jGXPGvCuMDSPh4ww/N0= =DcXD -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
0b9df43619
6 changed files with 47 additions and 17 deletions
|
@ -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,7 +294,10 @@ 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];
|
||||||
|
|
||||||
error = gpiod_get_array_value(j, descs, NULL, values);
|
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);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -328,7 +332,10 @@ 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);
|
||||||
|
|
||||||
gpiod_set_value(fwd->descs[offset], value);
|
if (chip->can_sleep)
|
||||||
|
gpiod_set_value_cansleep(fwd->descs[offset], value);
|
||||||
|
else
|
||||||
|
gpiod_set_value(fwd->descs[offset], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
||||||
|
@ -343,7 +350,10 @@ static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
|
||||||
descs[j++] = fwd->descs[i];
|
descs[j++] = fwd->descs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
gpiod_set_array_value(j, descs, NULL, values);
|
if (fwd->chip.can_sleep)
|
||||||
|
gpiod_set_array_value_cansleep(j, descs, NULL, values);
|
||||||
|
else
|
||||||
|
gpiod_set_array_value(j, descs, NULL, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpio_fwd_set_multiple_locked(struct gpio_chip *chip,
|
static void gpio_fwd_set_multiple_locked(struct gpio_chip *chip,
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
hog->chip_label = kasprintf(GFP_KERNEL,
|
if (gpio_sim_bank_has_label(bank))
|
||||||
"gpio-sim.%u-%s", dev->id,
|
hog->chip_label = kstrdup(bank->label,
|
||||||
fwnode_get_name(bank->swnode));
|
GFP_KERNEL);
|
||||||
|
else
|
||||||
|
hog->chip_label = kasprintf(GFP_KERNEL,
|
||||||
|
"gpio-sim.%u-%s",
|
||||||
|
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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
* 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 {
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue