Skip to content

Commit

Permalink
gpiolib: acpi: avoid leaking ACPI details into upper gpiolib layers
Browse files Browse the repository at this point in the history
There is no need for the generic parts of GPIOLIB to be aware of
implementation details of ACPI-bases lookups.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
  • Loading branch information
Dmitry Torokhov authored and Bartosz Golaszewski committed Nov 15, 2022
1 parent 16ba046 commit b7452d6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 57 deletions.
51 changes: 43 additions & 8 deletions drivers/gpio/gpiolib-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,30 @@ struct acpi_gpio_chip {
struct list_head deferred_req_irqs_list_entry;
};

/**
* 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
* @pin_config: pin bias as provided by ACPI
* @polarity: interrupt polarity as provided by ACPI
* @triggering: triggering type as provided by ACPI
* @wake_capable: wake capability as provided by ACPI
* @debounce: debounce timeout 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 pin_config;
int polarity;
int triggering;
bool wake_capable;
unsigned int debounce;
unsigned int quirks;
};

/*
* For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init
* (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a
Expand Down Expand Up @@ -670,8 +694,8 @@ __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)
static 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;
Expand All @@ -690,8 +714,8 @@ acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *inf
return ret;
}

int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
struct acpi_gpio_info *info)
static int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
struct acpi_gpio_info *info)
{
switch (info->pin_config) {
case ACPI_PIN_CONFIG_PULLUP:
Expand Down Expand Up @@ -1005,7 +1029,8 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
* @fwnode: pointer to an ACPI firmware node to get the GPIO information from
* @propname: Property name of the GPIO
* @index: index of GpioIo/GpioInt resource (starting from %0)
* @info: info pointer to fill in (optional)
* @lflags: bitmask of gpio_lookup_flags GPIO_* values
* @dflags: gpiod initialization flags
*
* If @fwnode is an ACPI device object, call acpi_get_gpiod_by_index() for it.
* Otherwise (i.e. it is a data-only non-device object), use the property-based
Expand All @@ -1017,15 +1042,25 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
*/
struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
const char *propname, int index,
struct acpi_gpio_info *info)
unsigned long *lflags,
enum gpiod_flags *dflags)
{
struct acpi_gpio_info info;
struct acpi_device *adev;
struct gpio_desc *desc;

adev = to_acpi_device_node(fwnode);
if (adev)
return acpi_get_gpiod_by_index(adev, propname, index, info);
desc = acpi_get_gpiod_by_index(adev, propname, index, &info);
else
desc = acpi_get_gpiod_from_data(fwnode, propname, index, &info);

return acpi_get_gpiod_from_data(fwnode, propname, index, info);
if (!IS_ERR(desc)) {
acpi_gpio_update_gpiod_flags(dflags, &info);
acpi_gpio_update_gpiod_lookup_flags(lflags, &info);
}

return desc;
}

/**
Expand Down
46 changes: 3 additions & 43 deletions drivers/gpio/gpiolib-acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,6 @@

struct acpi_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
* @pin_config: pin bias as provided by ACPI
* @polarity: interrupt polarity as provided by ACPI
* @triggering: triggering type as provided by ACPI
* @wake_capable: wake capability as provided by ACPI
* @debounce: debounce timeout 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 pin_config;
int polarity;
int triggering;
bool wake_capable;
unsigned int debounce;
unsigned int quirks;
};

#ifdef CONFIG_ACPI
void acpi_gpiochip_add(struct gpio_chip *chip);
void acpi_gpiochip_remove(struct gpio_chip *chip);
Expand All @@ -43,19 +19,15 @@ void acpi_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev);
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,
struct acpi_gpio_info *info);
int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
struct acpi_gpio_info *info);

struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
const char *con_id,
unsigned int idx,
enum gpiod_flags *dflags,
unsigned long *lookupflags);
struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
const char *propname, int index,
struct acpi_gpio_info *info);
unsigned long *lflags,
enum gpiod_flags *dflags);

int acpi_gpio_count(struct device *dev, const char *con_id);
#else
Expand All @@ -70,18 +42,6 @@ acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { }
static inline void
acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }

static inline int
acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info)
{
return 0;
}
static inline int
acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
struct acpi_gpio_info *info)
{
return 0;
}

static inline struct gpio_desc *
acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id,
unsigned int idx, enum gpiod_flags *dflags,
Expand All @@ -91,7 +51,7 @@ acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id,
}
static inline struct gpio_desc *
acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
int index, struct acpi_gpio_info *info)
int index, unsigned long *lflags, enum gpiod_flags *dflags)
{
return ERR_PTR(-ENXIO);
}
Expand Down
8 changes: 2 additions & 6 deletions drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3890,14 +3890,10 @@ static struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
label);
return desc;
} else if (is_acpi_node(fwnode)) {
struct acpi_gpio_info info;

desc = acpi_node_get_gpiod(fwnode, propname, index, &info);
desc = acpi_node_get_gpiod(fwnode, propname, index,
&lflags, &dflags);
if (IS_ERR(desc))
return desc;

acpi_gpio_update_gpiod_flags(&dflags, &info);
acpi_gpio_update_gpiod_lookup_flags(&lflags, &info);
} else {
return ERR_PTR(-EINVAL);
}
Expand Down

0 comments on commit b7452d6

Please sign in to comment.