Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f7194a1 authored by Mika Westerberg's avatar Mika Westerberg Committed by Linus Walleij
Browse files

ACPI / gpio: Allow holes in list of GPIOs for a device



Make it possible to have an empty GPIOs in a GPIO list for device. For
example a SPI master may use both GPIOs and native pins as chip selects and
we need to be able to distinguish between the two.

This makes it mandatory to have exactly 3 arguments for GPIOs and then
converts gpiolib to use of __acpi_node_get_property_reference() instead. In
addition we make acpi_gpio_package_count() to handle holes as well (this
matches the DT version).

Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 1208c935
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -51,6 +51,21 @@ it to 1 marks the GPIO as active low.
In our Bluetooth example the "reset-gpios" refers to the second GpioIo()
In our Bluetooth example the "reset-gpios" refers to the second GpioIo()
resource, second pin in that resource with the GPIO number of 31.
resource, second pin in that resource with the GPIO number of 31.


It is possible to leave holes in the array of GPIOs. This is useful in
cases like with SPI host controllers where some chip selects may be
implemented as GPIOs and some as native signals. For example a SPI host
controller can have chip selects 0 and 2 implemented as GPIOs and 1 as
native:

  Package () {
      "cs-gpios",
      Package () {
          ^GPIO, 19, 0, 0, // chip select 0: GPIO
          0,               // chip select 1: native signal
          ^GPIO, 20, 0, 0, // chip select 2: GPIO
      }
  }

ACPI GPIO Mappings Provided by Drivers
ACPI GPIO Mappings Provided by Drivers
--------------------------------------
--------------------------------------


+21 −11
Original line number Original line Diff line number Diff line
@@ -468,7 +468,8 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
	int ret;
	int ret;


	memset(&args, 0, sizeof(args));
	memset(&args, 0, sizeof(args));
	ret = acpi_node_get_property_reference(fwnode, propname, index, &args);
	ret = __acpi_node_get_property_reference(fwnode, propname, index, 3,
						 &args);
	if (ret) {
	if (ret) {
		struct acpi_device *adev = to_acpi_device_node(fwnode);
		struct acpi_device *adev = to_acpi_device_node(fwnode);


@@ -483,13 +484,13 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
	 * on returned args.
	 * on returned args.
	 */
	 */
	lookup->adev = args.adev;
	lookup->adev = args.adev;
	if (args.nargs >= 2) {
	if (args.nargs != 3)
		return -EPROTO;

	lookup->index = args.args[0];
	lookup->index = args.args[0];
	lookup->pin_index = args.args[1];
	lookup->pin_index = args.args[1];
		/* 3rd argument, if present is used to specify active_low. */
		if (args.nargs >= 3)
	lookup->active_low = !!args.args[2];
	lookup->active_low = !!args.args[2];
	}

	return 0;
	return 0;
}
}


@@ -915,18 +916,27 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
	kfree(acpi_gpio);
	kfree(acpi_gpio);
}
}


static unsigned int acpi_gpio_package_count(const union acpi_object *obj)
static int acpi_gpio_package_count(const union acpi_object *obj)
{
{
	const union acpi_object *element = obj->package.elements;
	const union acpi_object *element = obj->package.elements;
	const union acpi_object *end = element + obj->package.count;
	const union acpi_object *end = element + obj->package.count;
	unsigned int count = 0;
	unsigned int count = 0;


	while (element < end) {
	while (element < end) {
		if (element->type == ACPI_TYPE_LOCAL_REFERENCE)
		switch (element->type) {
		case ACPI_TYPE_LOCAL_REFERENCE:
			element += 3;
			/* Fallthrough */
		case ACPI_TYPE_INTEGER:
			element++;
			count++;
			count++;
			break;


		element++;
		default:
			return -EPROTO;
		}
		}
	}

	return count;
	return count;
}
}