Loading drivers/gpio/gpiolib-acpi.c +38 −19 Original line number Diff line number Diff line Loading @@ -414,7 +414,8 @@ EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios); static bool acpi_get_driver_gpio_data(struct acpi_device *adev, const char *name, int index, struct acpi_reference_args *args) struct acpi_reference_args *args, unsigned int *quirks) { const struct acpi_gpio_mapping *gm; Loading @@ -430,6 +431,8 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev, args->args[1] = par->line_index; args->args[2] = par->active_low; args->nargs = 3; *quirks = gm->quirks; return true; } Loading Loading @@ -461,8 +464,8 @@ acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio) } } int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) static int __acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) { int ret = 0; Loading @@ -489,12 +492,31 @@ acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) return ret; } int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info) { struct device *dev = &info->adev->dev; enum gpiod_flags old = *flags; int ret; ret = __acpi_gpio_update_gpiod_flags(&old, info->flags); if (info->quirks & ACPI_GPIO_QUIRK_NO_IO_RESTRICTION) { if (ret) dev_warn(dev, FW_BUG "GPIO not in correct mode, fixing\n"); } else { if (ret) dev_dbg(dev, "Override GPIO initialization flags\n"); *flags = old; } return ret; } struct acpi_gpio_lookup { struct acpi_gpio_info info; int index; int pin_index; bool active_low; struct acpi_device *adev; struct gpio_desc *desc; int n; }; Loading Loading @@ -531,8 +553,8 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) lookup->info.triggering = agpio->triggering; } else { lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio); lookup->info.polarity = lookup->active_low; } } return 1; Loading @@ -541,12 +563,13 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, struct acpi_gpio_info *info) { struct acpi_device *adev = lookup->info.adev; struct list_head res_list; int ret; INIT_LIST_HEAD(&res_list); ret = acpi_dev_get_resources(lookup->adev, &res_list, ret = acpi_dev_get_resources(adev, &res_list, acpi_populate_gpio_lookup, lookup); if (ret < 0) Loading @@ -557,11 +580,8 @@ static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, if (!lookup->desc) return -ENOENT; if (info) { if (info) *info = lookup->info; if (lookup->active_low) info->polarity = lookup->active_low; } return 0; } Loading @@ -570,6 +590,7 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, struct acpi_gpio_lookup *lookup) { struct acpi_reference_args args; unsigned int quirks = 0; int ret; memset(&args, 0, sizeof(args)); Loading @@ -581,14 +602,14 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, if (!adev) return ret; if (!acpi_get_driver_gpio_data(adev, propname, index, &args)) if (!acpi_get_driver_gpio_data(adev, propname, index, &args, &quirks)) return ret; } /* * The property was found and resolved, so need to lookup the GPIO based * on returned args. */ lookup->adev = args.adev; if (args.nargs != 3) return -EPROTO; Loading @@ -596,6 +617,8 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, lookup->pin_index = args.args[1]; lookup->active_low = !!args.args[2]; lookup->info.adev = args.adev; lookup->info.quirks = quirks; return 0; } Loading Loading @@ -643,11 +666,11 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, return ERR_PTR(ret); dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n", dev_name(&lookup.adev->dev), lookup.index, dev_name(&lookup.info.adev->dev), lookup.index, lookup.pin_index, lookup.active_low); } else { dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index); lookup.adev = adev; lookup.info.adev = adev; } ret = acpi_gpio_resource_lookup(&lookup, info); Loading @@ -664,7 +687,6 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, struct acpi_gpio_info info; struct gpio_desc *desc; char propname[32]; int err; int i; /* Try first from _DSD */ Loading Loading @@ -703,10 +725,7 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, if (info.polarity == GPIO_ACTIVE_LOW) *lookupflags |= GPIO_ACTIVE_LOW; err = acpi_gpio_update_gpiod_flags(dflags, info.flags); if (err) dev_dbg(dev, "Override GPIO initialization flags\n"); acpi_gpio_update_gpiod_flags(dflags, &info); return desc; } Loading drivers/gpio/gpiolib.c +1 −3 Original line number Diff line number Diff line Loading @@ -3690,9 +3690,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, desc = acpi_node_get_gpiod(fwnode, propname, index, &info); if (!IS_ERR(desc)) { active_low = info.polarity == GPIO_ACTIVE_LOW; ret = acpi_gpio_update_gpiod_flags(&dflags, info.flags); if (ret) pr_debug("Override GPIO initialization flags\n"); acpi_gpio_update_gpiod_flags(&dflags, &info); } } Loading drivers/gpio/gpiolib.h +6 −2 Original line number Diff line number Diff line Loading @@ -75,16 +75,20 @@ struct gpio_device { /** * struct acpi_gpio_info - ACPI GPIO specific information * @adev: reference to ACPI device which consumes GPIO resource * @flags: GPIO initialization flags * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo * @polarity: interrupt polarity as provided by ACPI * @triggering: triggering type as provided by ACPI * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping */ struct acpi_gpio_info { struct acpi_device *adev; enum gpiod_flags flags; bool gpioint; int polarity; int triggering; unsigned int quirks; }; /* gpio suffixes used for ACPI and device tree lookup */ Loading Loading @@ -124,7 +128,7 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update); struct acpi_gpio_info *info); struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, Loading @@ -149,7 +153,7 @@ static inline void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } static inline int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info) { return 0; } Loading include/linux/acpi.h +5 −0 Original line number Diff line number Diff line Loading @@ -978,6 +978,11 @@ struct acpi_gpio_mapping { const char *name; const struct acpi_gpio_params *data; unsigned int size; /* Ignore IoRestriction field */ #define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION BIT(0) unsigned int quirks; }; #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB) Loading Loading
drivers/gpio/gpiolib-acpi.c +38 −19 Original line number Diff line number Diff line Loading @@ -414,7 +414,8 @@ EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios); static bool acpi_get_driver_gpio_data(struct acpi_device *adev, const char *name, int index, struct acpi_reference_args *args) struct acpi_reference_args *args, unsigned int *quirks) { const struct acpi_gpio_mapping *gm; Loading @@ -430,6 +431,8 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev, args->args[1] = par->line_index; args->args[2] = par->active_low; args->nargs = 3; *quirks = gm->quirks; return true; } Loading Loading @@ -461,8 +464,8 @@ acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio) } } int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) static int __acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) { int ret = 0; Loading @@ -489,12 +492,31 @@ acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) return ret; } int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info) { struct device *dev = &info->adev->dev; enum gpiod_flags old = *flags; int ret; ret = __acpi_gpio_update_gpiod_flags(&old, info->flags); if (info->quirks & ACPI_GPIO_QUIRK_NO_IO_RESTRICTION) { if (ret) dev_warn(dev, FW_BUG "GPIO not in correct mode, fixing\n"); } else { if (ret) dev_dbg(dev, "Override GPIO initialization flags\n"); *flags = old; } return ret; } struct acpi_gpio_lookup { struct acpi_gpio_info info; int index; int pin_index; bool active_low; struct acpi_device *adev; struct gpio_desc *desc; int n; }; Loading Loading @@ -531,8 +553,8 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) lookup->info.triggering = agpio->triggering; } else { lookup->info.flags = acpi_gpio_to_gpiod_flags(agpio); lookup->info.polarity = lookup->active_low; } } return 1; Loading @@ -541,12 +563,13 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, struct acpi_gpio_info *info) { struct acpi_device *adev = lookup->info.adev; struct list_head res_list; int ret; INIT_LIST_HEAD(&res_list); ret = acpi_dev_get_resources(lookup->adev, &res_list, ret = acpi_dev_get_resources(adev, &res_list, acpi_populate_gpio_lookup, lookup); if (ret < 0) Loading @@ -557,11 +580,8 @@ static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, if (!lookup->desc) return -ENOENT; if (info) { if (info) *info = lookup->info; if (lookup->active_low) info->polarity = lookup->active_low; } return 0; } Loading @@ -570,6 +590,7 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, struct acpi_gpio_lookup *lookup) { struct acpi_reference_args args; unsigned int quirks = 0; int ret; memset(&args, 0, sizeof(args)); Loading @@ -581,14 +602,14 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, if (!adev) return ret; if (!acpi_get_driver_gpio_data(adev, propname, index, &args)) if (!acpi_get_driver_gpio_data(adev, propname, index, &args, &quirks)) return ret; } /* * The property was found and resolved, so need to lookup the GPIO based * on returned args. */ lookup->adev = args.adev; if (args.nargs != 3) return -EPROTO; Loading @@ -596,6 +617,8 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, lookup->pin_index = args.args[1]; lookup->active_low = !!args.args[2]; lookup->info.adev = args.adev; lookup->info.quirks = quirks; return 0; } Loading Loading @@ -643,11 +666,11 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, return ERR_PTR(ret); dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n", dev_name(&lookup.adev->dev), lookup.index, dev_name(&lookup.info.adev->dev), lookup.index, lookup.pin_index, lookup.active_low); } else { dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index); lookup.adev = adev; lookup.info.adev = adev; } ret = acpi_gpio_resource_lookup(&lookup, info); Loading @@ -664,7 +687,6 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, struct acpi_gpio_info info; struct gpio_desc *desc; char propname[32]; int err; int i; /* Try first from _DSD */ Loading Loading @@ -703,10 +725,7 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, if (info.polarity == GPIO_ACTIVE_LOW) *lookupflags |= GPIO_ACTIVE_LOW; err = acpi_gpio_update_gpiod_flags(dflags, info.flags); if (err) dev_dbg(dev, "Override GPIO initialization flags\n"); acpi_gpio_update_gpiod_flags(dflags, &info); return desc; } Loading
drivers/gpio/gpiolib.c +1 −3 Original line number Diff line number Diff line Loading @@ -3690,9 +3690,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, desc = acpi_node_get_gpiod(fwnode, propname, index, &info); if (!IS_ERR(desc)) { active_low = info.polarity == GPIO_ACTIVE_LOW; ret = acpi_gpio_update_gpiod_flags(&dflags, info.flags); if (ret) pr_debug("Override GPIO initialization flags\n"); acpi_gpio_update_gpiod_flags(&dflags, &info); } } Loading
drivers/gpio/gpiolib.h +6 −2 Original line number Diff line number Diff line Loading @@ -75,16 +75,20 @@ struct gpio_device { /** * struct acpi_gpio_info - ACPI GPIO specific information * @adev: reference to ACPI device which consumes GPIO resource * @flags: GPIO initialization flags * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo * @polarity: interrupt polarity as provided by ACPI * @triggering: triggering type as provided by ACPI * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping */ struct acpi_gpio_info { struct acpi_device *adev; enum gpiod_flags flags; bool gpioint; int polarity; int triggering; unsigned int quirks; }; /* gpio suffixes used for ACPI and device tree lookup */ Loading Loading @@ -124,7 +128,7 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update); struct acpi_gpio_info *info); struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, Loading @@ -149,7 +153,7 @@ static inline void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } static inline int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info) { return 0; } Loading
include/linux/acpi.h +5 −0 Original line number Diff line number Diff line Loading @@ -978,6 +978,11 @@ struct acpi_gpio_mapping { const char *name; const struct acpi_gpio_params *data; unsigned int size; /* Ignore IoRestriction field */ #define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION BIT(0) unsigned int quirks; }; #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB) Loading