Commit 3b144038 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'intel-gpio-v6.10-2' of...

Merge tag 'intel-gpio-v6.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel

Pull intel-gpio fixes from Andy Shevchenko:

 - NULL pointer dereference fix in GPIO APCI library

 - Restore ACPI handle matching for GPIO devices represented in banks

* tag 'intel-gpio-v6.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel:
  gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent node match
  gpiolib: acpi: Move ACPI device NULL check to acpi_can_fallback_to_crs()
parents b9dd56e8 adbc49a5
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -128,7 +128,24 @@ static bool acpi_gpio_deferred_req_irqs_done;

static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data)
{
	return device_match_acpi_handle(&gc->gpiodev->dev, data);
	/* First check the actual GPIO device */
	if (device_match_acpi_handle(&gc->gpiodev->dev, data))
		return true;

	/*
	 * When the ACPI device is artificially split to the banks of GPIOs,
	 * where each of them is represented by a separate GPIO device,
	 * the firmware node of the physical device may not be shared among
	 * the banks as they may require different values for the same property,
	 * e.g., number of GPIOs in a certain bank. In such case the ACPI handle
	 * of a GPIO device is NULL and can not be used. Hence we have to check
	 * the parent device to be sure that there is no match before bailing
	 * out.
	 */
	if (gc->parent)
		return device_match_acpi_handle(gc->parent, data);

	return false;
}

/**
@@ -938,6 +955,10 @@ static struct gpio_desc *acpi_get_gpiod_from_data(struct fwnode_handle *fwnode,
static bool acpi_can_fallback_to_crs(struct acpi_device *adev,
				     const char *con_id)
{
	/* If there is no ACPI device, there is no _CRS to fall back to */
	if (!adev)
		return false;

	/* Never allow fallback if the device has properties */
	if (acpi_dev_has_props(adev) || adev->driver_gpios)
		return false;
@@ -978,10 +999,10 @@ __acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int
	}

	/* Then from plain _CRS GPIOs */
	if (!adev || !can_fallback)
		return ERR_PTR(-ENOENT);

	if (can_fallback)
		return acpi_get_gpiod_by_index(adev, NULL, idx, info);

	return ERR_PTR(-ENOENT);
}

struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,