Skip to content

Commit

Permalink
gpiolib: acpi: Add wake_capable variants of acpi_dev_gpio_irq_get
Browse files Browse the repository at this point in the history
The ACPI spec defines the SharedAndWake and ExclusiveAndWake share type
keywords. This is an indication that the GPIO IRQ can also be used as a
wake source. This change exposes the wake_capable bit so drivers can
correctly enable wake functionality instead of making an assumption.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Raul E Rangel authored and rafaeljw committed Oct 4, 2022
1 parent f76349c commit 4c99256
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
15 changes: 12 additions & 3 deletions drivers/gpio/gpiolib-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
lookup->info.pin_config = agpio->pin_config;
lookup->info.debounce = agpio->debounce_timeout;
lookup->info.gpioint = gpioint;
lookup->info.wake_capable = agpio->wake_capable == ACPI_WAKE_CAPABLE;

/*
* Polarity and triggering are only specified for GpioInt
Expand Down Expand Up @@ -987,10 +988,11 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
}

/**
* acpi_dev_gpio_irq_get_by() - Find GpioInt and translate it to Linux IRQ number
* acpi_dev_gpio_irq_wake_get_by() - Find GpioInt and translate it to Linux IRQ number
* @adev: pointer to a ACPI device to get IRQ from
* @name: optional name of GpioInt resource
* @index: index of GpioInt resource (starting from %0)
* @wake_capable: Set to true if the IRQ is wake capable
*
* If the device has one or more GpioInt resources, this function can be
* used to translate from the GPIO offset in the resource to the Linux IRQ
Expand All @@ -1002,9 +1004,13 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
* The function takes optional @name parameter. If the resource has a property
* name, then only those will be taken into account.
*
* The GPIO is considered wake capable if the GpioInt resource specifies
* SharedAndWake or ExclusiveAndWake.
*
* Return: Linux IRQ number (> %0) on success, negative errno on failure.
*/
int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index)
int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *name, int index,
bool *wake_capable)
{
int idx, i;
unsigned int irq_flags;
Expand Down Expand Up @@ -1061,13 +1067,16 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind
dev_dbg(&adev->dev, "IRQ %d already in use\n", irq);
}

if (wake_capable)
*wake_capable = info.wake_capable;

return irq;
}

}
return -ENOENT;
}
EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get_by);
EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_wake_get_by);

static acpi_status
acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpio/gpiolib-acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct acpi_device;
* @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
*/
Expand All @@ -28,6 +29,7 @@ struct acpi_gpio_info {
int pin_config;
int polarity;
int triggering;
bool wake_capable;
unsigned int debounce;
unsigned int quirks;
};
Expand Down
21 changes: 17 additions & 4 deletions include/linux/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,8 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio);
bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio);
int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index);
int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *name, int index,
bool *wake_capable);
#else
static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio)
Expand All @@ -1214,16 +1215,28 @@ static inline bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
{
return false;
}
static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
const char *name, int index)
static inline int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *name,
int index, bool *wake_capable)
{
return -ENXIO;
}
#endif

static inline int acpi_dev_gpio_irq_wake_get(struct acpi_device *adev, int index,
bool *wake_capable)
{
return acpi_dev_gpio_irq_wake_get_by(adev, NULL, index, wake_capable);
}

static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name,
int index)
{
return acpi_dev_gpio_irq_wake_get_by(adev, name, index, NULL);
}

static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
{
return acpi_dev_gpio_irq_get_by(adev, NULL, index);
return acpi_dev_gpio_irq_wake_get_by(adev, NULL, index, NULL);
}

/* Device properties */
Expand Down

0 comments on commit 4c99256

Please sign in to comment.