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: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
1208c93525
commit
6f7194a10b
@ -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
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
@ -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)
|
||||||
lookup->index = args.args[0];
|
return -EPROTO;
|
||||||
lookup->pin_index = args.args[1];
|
|
||||||
/* 3rd argument, if present is used to specify active_low. */
|
lookup->index = args.args[0];
|
||||||
if (args.nargs >= 3)
|
lookup->pin_index = args.args[1];
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user