From: Mika Westerberg Date: Mon, 5 Jun 2017 08:39:25 +0000 (+0800) Subject: ACPICA: ACPI 6.2: Add support for PinGroup() resource X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=fdaa0980772cb05b53e7f544d513e3445f3f1021;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git ACPICA: ACPI 6.2: Add support for PinGroup() resource ACPICA commit 7d928e3174fb19d7dc0066b03c30bea07c001563 ACPI 6.2 introduced a new resource that is used to declare set of pins belonging to a GPIO controller. This resource is referenced by new PinGroupFunction() and PinGroupConfig() resources using ResourceSource and ResourceLabel fields. The PinGroup() resource looks like this: PinGroup (ResourceLabel, ResourceUsage, DescriptorName, VendorData) {Pin List} This resource should be listed in _CRS under the GPIO/pincontroller device providing these pins. Link: https://github.com/acpica/acpica/commit/7d928e31 Signed-off-by: Mika Westerberg Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 115cadd54471..01b961c6b3f1 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1145,7 +1145,8 @@ struct acpi_port_info { #define ACPI_RESOURCE_NAME_PIN_FUNCTION 0x8D #define ACPI_RESOURCE_NAME_SERIAL_BUS 0x8E #define ACPI_RESOURCE_NAME_PIN_CONFIG 0x8F -#define ACPI_RESOURCE_NAME_LARGE_MAX 0x8F +#define ACPI_RESOURCE_NAME_PIN_GROUP 0x90 +#define ACPI_RESOURCE_NAME_LARGE_MAX 0x90 /***************************************************************************** * diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index 61d2ef38a8ed..63f2ab411682 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h @@ -148,7 +148,9 @@ typedef enum { ACPI_RSD_UINT16, ACPI_RSD_UINT32, ACPI_RSD_UINT64, - ACPI_RSD_WORDLIST + ACPI_RSD_WORDLIST, + ACPI_RSD_LABEL, + } ACPI_RSDUMP_OPCODES; /* restore default alignment */ @@ -331,6 +333,7 @@ extern struct acpi_rsconvert_info acpi_rs_convert_spi_serial_bus[]; extern struct acpi_rsconvert_info acpi_rs_convert_uart_serial_bus[]; extern struct acpi_rsconvert_info acpi_rs_convert_pin_function[]; extern struct acpi_rsconvert_info acpi_rs_convert_pin_config[]; +extern struct acpi_rsconvert_info acpi_rs_convert_pin_group[]; /* These resources require separate get/set tables */ @@ -382,6 +385,7 @@ extern struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[]; extern struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[]; extern struct acpi_rsdump_info acpi_rs_dump_general_flags[]; extern struct acpi_rsdump_info acpi_rs_dump_pin_config[]; +extern struct acpi_rsdump_info acpi_rs_dump_pin_group[]; #endif #endif /* __ACRESRC_H__ */ diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 6f8d8f903ffd..510c20d48192 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -447,6 +447,23 @@ struct aml_resource_pin_config { #define AML_RESOURCE_PIN_CONFIG_REVISION 1 /* ACPI 6.2 */ +struct aml_resource_pin_group { + AML_RESOURCE_LARGE_HEADER_COMMON u8 revision_id; + u16 flags; + u16 pin_table_offset; + u16 label_offset; + u16 vendor_offset; + u16 vendor_length; + /* + * Optional fields follow immediately: + * 1) PIN list (Words) + * 2) Resource Label String + * 3) Vendor Data bytes + */ +}; + +#define AML_RESOURCE_PIN_GROUP_REVISION 1 /* ACPI 6.2 */ + /* restore default alignment */ #pragma pack() @@ -491,6 +508,7 @@ union aml_resource { struct aml_resource_common_serialbus common_serial_bus; struct aml_resource_pin_function pin_function; struct aml_resource_pin_config pin_config; + struct aml_resource_pin_group pin_group; /* Utility overlays */ diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 9fdc9c187818..39cc7ffef3a4 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -389,6 +389,19 @@ acpi_rs_get_aml_length(struct acpi_resource *resource, break; + case ACPI_RESOURCE_TYPE_PIN_GROUP: + + total_size = (acpi_rs_length)(total_size + + (resource->data.pin_group. + pin_table_length * 2) + + resource->data.pin_group. + resource_label. + string_length + + resource->data.pin_group. + vendor_length); + + break; + default: break; @@ -612,6 +625,15 @@ acpi_rs_get_list_length(u8 *aml_buffer, } break; + case ACPI_RESOURCE_NAME_PIN_GROUP: + + extra_struct_bytes += + aml_resource->pin_group.vendor_offset - + aml_resource->pin_group.pin_table_offset + + aml_resource->pin_group.vendor_length; + + break; + default: break; diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index f4cdf8d832dc..608e36e91de6 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -75,6 +75,10 @@ static void acpi_rs_dump_short_byte_list(u8 length, u8 *data); static void acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source); +static void +acpi_rs_dump_resource_label(char *title, + struct acpi_resource_label *resource_label); + static void acpi_rs_dump_address_common(union acpi_resource_data *resource); static void @@ -371,6 +375,16 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) target)); break; + case ACPI_RSD_LABEL: + /* + * resource_label + */ + acpi_rs_dump_resource_label("Resource Label", + ACPI_CAST_PTR(struct + acpi_resource_label, + target)); + break; + default: acpi_os_printf("**** Invalid table opcode [%X] ****\n", @@ -412,6 +426,30 @@ acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source) resource_source->string_ptr : "[Not Specified]"); } +/******************************************************************************* + * + * FUNCTION: acpi_rs_dump_resource_label + * + * PARAMETERS: title - Title of the dumped resource field + * resource_label - Pointer to a Resource Label struct + * + * RETURN: None + * + * DESCRIPTION: Common routine for dumping the resource_label + * + ******************************************************************************/ + +static void +acpi_rs_dump_resource_label(char *title, + struct acpi_resource_label *resource_label) +{ + ACPI_FUNCTION_ENTRY(); + + acpi_rs_out_string(title, + resource_label->string_ptr ? + resource_label->string_ptr : "[Not Specified]"); +} + /******************************************************************************* * * FUNCTION: acpi_rs_dump_address_common diff --git a/drivers/acpi/acpica/rsdumpinfo.c b/drivers/acpi/acpica/rsdumpinfo.c index e68472248fff..30c34d579bda 100644 --- a/drivers/acpi/acpica/rsdumpinfo.c +++ b/drivers/acpi/acpica/rsdumpinfo.c @@ -362,6 +362,25 @@ struct acpi_rsdump_info acpi_rs_dump_pin_config[11] = { "VendorData", NULL}, }; +struct acpi_rsdump_info acpi_rs_dump_pin_group[8] = { + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_pin_group), + "PinGroup", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(pin_group.revision_id), "RevisionId", + NULL}, + {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(pin_group.producer_consumer), + "ProducerConsumer", acpi_gbl_consume_decode}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(pin_group.pin_table_length), + "PinTableLength", NULL}, + {ACPI_RSD_WORDLIST, ACPI_RSD_OFFSET(pin_group.pin_table), "PinTable", + NULL}, + {ACPI_RSD_LABEL, ACPI_RSD_OFFSET(pin_group.resource_label), + "ResourceLabel", NULL}, + {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(pin_group.vendor_length), + "VendorLength", NULL}, + {ACPI_RSD_SHORTLISTX, ACPI_RSD_OFFSET(pin_group.vendor_data), + "VendorData", NULL}, +}; + struct acpi_rsdump_info acpi_rs_dump_fixed_dma[4] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_dma), "FixedDma", NULL}, diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index 5634bd65a745..13c3d3656d92 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c @@ -82,6 +82,7 @@ struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = { NULL, /* 0x13, ACPI_RESOURCE_TYPE_SERIAL_BUS - Use subtype table below */ acpi_rs_convert_pin_function, /* 0x14, ACPI_RESOURCE_TYPE_PIN_FUNCTION */ acpi_rs_convert_pin_config, /* 0x15, ACPI_RESOURCE_TYPE_PIN_CONFIG */ + acpi_rs_convert_pin_group, /* 0x16, ACPI_RESOURCE_TYPE_PIN_GROUP */ }; /* Dispatch tables for AML-to-resource (Get Resource) conversion functions */ @@ -124,6 +125,7 @@ struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[] = { acpi_rs_convert_pin_function, /* 0x0D, ACPI_RESOURCE_NAME_PIN_FUNCTION */ NULL, /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use subtype table below */ acpi_rs_convert_pin_config, /* 0x0F, ACPI_RESOURCE_NAME_PIN_CONFIG */ + acpi_rs_convert_pin_group, /* 0x10, ACPI_RESOURCE_NAME_PIN_GROUP */ }; /* Subtype table for serial_bus -- I2C, SPI, and UART */ @@ -162,6 +164,7 @@ struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = { NULL, /* ACPI_RESOURCE_TYPE_SERIAL_BUS */ acpi_rs_dump_pin_function, /* ACPI_RESOURCE_TYPE_PIN_FUNCTION */ acpi_rs_dump_pin_config, /* ACPI_RESOURCE_TYPE_PIN_CONFIG */ + acpi_rs_dump_pin_group, /* ACPI_RESOURCE_TYPE_PIN_GROUP */ }; struct acpi_rsdump_info *acpi_gbl_dump_serial_bus_dispatch[] = { @@ -200,6 +203,7 @@ const u8 acpi_gbl_aml_resource_sizes[] = { sizeof(struct aml_resource_common_serialbus), /* ACPI_RESOURCE_TYPE_SERIAL_BUS */ sizeof(struct aml_resource_pin_function), /* ACPI_RESOURCE_TYPE_PIN_FUNCTION */ sizeof(struct aml_resource_pin_config), /* ACPI_RESOURCE_TYPE_PIN_CONFIG */ + sizeof(struct aml_resource_pin_group), /* ACPI_RESOURCE_TYPE_PIN_GROUP */ }; const u8 acpi_gbl_resource_struct_sizes[] = { @@ -240,6 +244,7 @@ const u8 acpi_gbl_resource_struct_sizes[] = { ACPI_RS_SIZE(struct acpi_resource_pin_function), ACPI_RS_SIZE(struct acpi_resource_common_serialbus), ACPI_RS_SIZE(struct acpi_resource_pin_config), + ACPI_RS_SIZE(struct acpi_resource_pin_group), }; const u8 acpi_gbl_aml_resource_serial_bus_sizes[] = { diff --git a/drivers/acpi/acpica/rsserial.c b/drivers/acpi/acpica/rsserial.c index 01bc851283d5..4a15893e0cf0 100644 --- a/drivers/acpi/acpica/rsserial.c +++ b/drivers/acpi/acpica/rsserial.c @@ -612,3 +612,65 @@ struct acpi_rsconvert_info acpi_rs_convert_pin_config[14] = { AML_OFFSET(pin_config.vendor_offset), 0}, }; + +/******************************************************************************* + * + * acpi_rs_convert_pin_group + * + ******************************************************************************/ + +struct acpi_rsconvert_info acpi_rs_convert_pin_group[10] = { + {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_PIN_GROUP, + ACPI_RS_SIZE(struct acpi_resource_pin_group), + ACPI_RSC_TABLE_SIZE(acpi_rs_convert_pin_group)}, + + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_PIN_GROUP, + sizeof(struct aml_resource_pin_group), + 0}, + + {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.pin_group.revision_id), + AML_OFFSET(pin_group.revision_id), + 1}, + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.pin_group.producer_consumer), + AML_OFFSET(pin_group.flags), + 0}, + + /* Pin Table */ + + /* + * It is OK to use GPIO operations here because none of them refer GPIO + * structures directly but instead use offsets given here. + */ + + {ACPI_RSC_COUNT_GPIO_PIN, + ACPI_RS_OFFSET(data.pin_group.pin_table_length), + AML_OFFSET(pin_group.pin_table_offset), + AML_OFFSET(pin_group.label_offset)}, + + {ACPI_RSC_MOVE_GPIO_PIN, ACPI_RS_OFFSET(data.pin_group.pin_table), + AML_OFFSET(pin_group.pin_table_offset), + 0}, + + /* Resource Label */ + + {ACPI_RSC_COUNT_GPIO_RES, + ACPI_RS_OFFSET(data.pin_group.resource_label.string_length), + AML_OFFSET(pin_group.label_offset), + AML_OFFSET(pin_group.vendor_offset)}, + + {ACPI_RSC_MOVE_GPIO_RES, + ACPI_RS_OFFSET(data.pin_group.resource_label.string_ptr), + AML_OFFSET(pin_group.label_offset), + 0}, + + /* Vendor Data */ + + {ACPI_RSC_COUNT_GPIO_VEN, ACPI_RS_OFFSET(data.pin_group.vendor_length), + AML_OFFSET(pin_group.vendor_length), + 1}, + + {ACPI_RSC_MOVE_GPIO_RES, ACPI_RS_OFFSET(data.pin_group.vendor_data), + AML_OFFSET(pin_group.vendor_offset), + 0}, +}; diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 2d3e9888837d..946e1e2cda0c 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -354,6 +354,7 @@ const u8 acpi_gbl_resource_aml_sizes[] = { ACPI_AML_SIZE_LARGE(struct aml_resource_pin_function), ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus), ACPI_AML_SIZE_LARGE(struct aml_resource_pin_config), + ACPI_AML_SIZE_LARGE(struct aml_resource_pin_group), }; const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = { @@ -407,6 +408,7 @@ static const u8 acpi_gbl_resource_types[] = { ACPI_VARIABLE_LENGTH, /* 0D pin_function */ ACPI_VARIABLE_LENGTH, /* 0E *serial_bus */ ACPI_VARIABLE_LENGTH, /* 0F pin_config */ + ACPI_VARIABLE_LENGTH, /* 10 pin_group */ }; /******************************************************************************* diff --git a/include/acpi/acrestyp.h b/include/acpi/acrestyp.h index 2b41ed163730..d29841bfc462 100644 --- a/include/acpi/acrestyp.h +++ b/include/acpi/acrestyp.h @@ -289,6 +289,11 @@ union acpi_resource_attribute { u8 type_specific; }; +struct acpi_resource_label { + u16 string_length; + char *string_ptr; +}; + struct acpi_resource_source { u8 index; u16 string_length; @@ -576,6 +581,16 @@ struct acpi_resource_pin_config { #define ACPI_PIN_CONFIG_INPUT_DEBOUNCE 12 #define ACPI_PIN_CONFIG_INPUT_SCHMITT_TRIGGER 13 +struct acpi_resource_pin_group { + u8 revision_id; + u8 producer_consumer; /* For values, see Producer/Consumer above */ + u16 pin_table_length; + u16 vendor_length; + u16 *pin_table; + struct acpi_resource_label resource_label; + u8 *vendor_data; +}; + /* ACPI_RESOURCE_TYPEs */ #define ACPI_RESOURCE_TYPE_IRQ 0 @@ -600,7 +615,8 @@ struct acpi_resource_pin_config { #define ACPI_RESOURCE_TYPE_SERIAL_BUS 19 /* ACPI 5.0 */ #define ACPI_RESOURCE_TYPE_PIN_FUNCTION 20 /* ACPI 6.2 */ #define ACPI_RESOURCE_TYPE_PIN_CONFIG 21 /* ACPI 6.2 */ -#define ACPI_RESOURCE_TYPE_MAX 21 +#define ACPI_RESOURCE_TYPE_PIN_GROUP 22 /* ACPI 6.2 */ +#define ACPI_RESOURCE_TYPE_MAX 22 /* Master union for resource descriptors */ @@ -630,6 +646,7 @@ union acpi_resource_data { struct acpi_resource_common_serialbus common_serial_bus; struct acpi_resource_pin_function pin_function; struct acpi_resource_pin_config pin_config; + struct acpi_resource_pin_group pin_group; /* Common fields */