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

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
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -922,3 +922,46 @@ int acpi_gpio_count(struct device *dev, const char *con_id)
	}
	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));
}
+3 −0
Original line number Diff line number Diff line
@@ -1868,6 +1868,9 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,

	/* Then from plain _CRS GPIOs */
	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);
		if (IS_ERR(desc))
			return desc;
+8 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
				      struct acpi_gpio_info *info);

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
static inline void acpi_gpiochip_add(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)
{
	return -ENODEV;
}

static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev,
					    const char *con_id)
{
	return false;
}
#endif

struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,