Commit 7f0ad539 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Merge branch 'for-dmitry' of...

Merge branch 'for-dmitry' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio into goodix

Bring in changes to ACPI GPIOLIB to better handle legacy ACPI mappings
needed for subsequent Goodix driver changes.
parents 9f9499ae 10cf4899
...@@ -922,3 +922,46 @@ int acpi_gpio_count(struct device *dev, const char *con_id) ...@@ -922,3 +922,46 @@ int acpi_gpio_count(struct device *dev, const char *con_id)
} }
return count; return count;
} }
struct acpi_crs_lookup {
struct list_head node;
struct acpi_device *adev;
const char *con_id;
};
static DEFINE_MUTEX(acpi_crs_lookup_lock);
static LIST_HEAD(acpi_crs_lookup_list);
bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id)
{
struct acpi_crs_lookup *l, *lookup = NULL;
/* Never allow fallback if the device has properties */
if (adev->data.properties || adev->driver_gpios)
return false;
mutex_lock(&acpi_crs_lookup_lock);
list_for_each_entry(l, &acpi_crs_lookup_list, node) {
if (l->adev == adev) {
lookup = l;
break;
}
}
if (!lookup) {
lookup = kmalloc(sizeof(*lookup), GFP_KERNEL);
if (lookup) {
lookup->adev = adev;
lookup->con_id = con_id;
list_add_tail(&lookup->node, &acpi_crs_lookup_list);
}
}
mutex_unlock(&acpi_crs_lookup_lock);
return lookup &&
((!lookup->con_id && !con_id) ||
(lookup->con_id && con_id &&
strcmp(lookup->con_id, con_id) == 0));
}
...@@ -1868,6 +1868,9 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, ...@@ -1868,6 +1868,9 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
/* Then from plain _CRS GPIOs */ /* Then from plain _CRS GPIOs */
if (IS_ERR(desc)) { if (IS_ERR(desc)) {
if (!acpi_can_fallback_to_crs(adev, con_id))
return ERR_PTR(-ENOENT);
desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info); desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
if (IS_ERR(desc)) if (IS_ERR(desc))
return desc; return desc;
......
...@@ -47,6 +47,8 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, ...@@ -47,6 +47,8 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
struct acpi_gpio_info *info); struct acpi_gpio_info *info);
int acpi_gpio_count(struct device *dev, const char *con_id); int acpi_gpio_count(struct device *dev, const char *con_id);
bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id);
#else #else
static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { }
...@@ -73,6 +75,12 @@ static inline int acpi_gpio_count(struct device *dev, const char *con_id) ...@@ -73,6 +75,12 @@ static inline int acpi_gpio_count(struct device *dev, const char *con_id)
{ {
return -ENODEV; return -ENODEV;
} }
static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev,
const char *con_id)
{
return false;
}
#endif #endif
struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
......
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