Blob Blame History Raw
From: Mika Westerberg <mika.westerberg@linux.intel.com>
Date: Mon, 5 Jun 2017 16:39:25 +0800
Subject: ACPICA: ACPI 6.2: Add support for PinGroup() resource
Patch-mainline: v4.13-rc1
Git-commit: fdaa0980772cb05b53e7f544d513e3445f3f1021
References: bsc#1117419

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 <mika.westerberg@linux.intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Lee, Chun-Yi <jlee@suse.com>
---
 drivers/acpi/acpica/aclocal.h    |    3 +
 drivers/acpi/acpica/acresrc.h    |    6 +++
 drivers/acpi/acpica/amlresrc.h   |   18 +++++++++++
 drivers/acpi/acpica/rscalc.c     |   22 +++++++++++++
 drivers/acpi/acpica/rsdump.c     |   38 +++++++++++++++++++++++
 drivers/acpi/acpica/rsdumpinfo.c |   19 +++++++++++
 drivers/acpi/acpica/rsinfo.c     |    5 +++
 drivers/acpi/acpica/rsserial.c   |   62 +++++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/utresrc.c    |    2 +
 include/acpi/acrestyp.h          |   19 +++++++++++
 10 files changed, 191 insertions(+), 3 deletions(-)

--- 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
 
 /*****************************************************************************
  *
--- 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_r
 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_d
 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__ */
--- 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 */
 
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -389,6 +389,19 @@ acpi_rs_get_aml_length(struct acpi_resou
 
 			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;
--- a/drivers/acpi/acpica/rsdump.c
+++ b/drivers/acpi/acpica/rsdump.c
@@ -75,6 +75,10 @@ static void acpi_rs_dump_short_byte_list
 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,
 								   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",
@@ -413,6 +427,30 @@ acpi_rs_dump_resource_source(struct acpi
 }
 
 /*******************************************************************************
+ *
+ * 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
  *
--- a/drivers/acpi/acpica/rsdumpinfo.c
+++ b/drivers/acpi/acpica/rsdumpinfo.c
@@ -362,6 +362,25 @@ struct acpi_rsdump_info acpi_rs_dump_pin
 	 "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},
--- a/drivers/acpi/acpica/rsinfo.c
+++ b/drivers/acpi/acpica/rsinfo.c
@@ -82,6 +82,7 @@ struct acpi_rsconvert_info *acpi_gbl_set
 	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
 	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_r
 	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[] = {
--- a/drivers/acpi/acpica/rsserial.c
+++ b/drivers/acpi/acpica/rsserial.c
@@ -612,3 +612,65 @@ struct acpi_rsconvert_info acpi_rs_conve
 	 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},
+};
--- 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 */
 };
 
 /*******************************************************************************
--- 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 */