ACPI 5.0: Support for all new resource descriptors

FixedDMA, GPIO descriptors, SerialBus descriptors

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c
index 1bfcef7..c446351 100644
--- a/drivers/acpi/acpica/rslist.c
+++ b/drivers/acpi/acpica/rslist.c
@@ -70,6 +70,8 @@
 	struct acpi_resource **resource_ptr =
 	    ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context);
 	struct acpi_resource *resource;
+	union aml_resource *aml_resource;
+	struct acpi_rsconvert_info *conversion_table;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(rs_convert_aml_to_resources);
@@ -84,14 +86,37 @@
 			      "Misaligned resource pointer %p", resource));
 	}
 
+	/* Get the appropriate conversion info table */
+
+	aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
+	if (acpi_ut_get_resource_type(aml) == ACPI_RESOURCE_NAME_SERIAL_BUS) {
+		if (aml_resource->common_serial_bus.type >
+		    AML_RESOURCE_MAX_SERIALBUSTYPE) {
+			conversion_table = NULL;
+		} else {
+			/* This is an I2C, SPI, or UART serial_bus descriptor */
+
+			conversion_table =
+			    acpi_gbl_convert_resource_serial_bus_dispatch
+			    [aml_resource->common_serial_bus.type];
+		}
+	} else {
+		conversion_table =
+		    acpi_gbl_get_resource_dispatch[resource_index];
+	}
+
+	if (!conversion_table) {
+		ACPI_ERROR((AE_INFO,
+			    "Invalid/unsupported resource descriptor: Type 0x%2.2X",
+			    resource_index));
+		return (AE_AML_INVALID_RESOURCE_TYPE);
+	}
+
 	/* Convert the AML byte stream resource to a local resource struct */
 
 	status =
-	    acpi_rs_convert_aml_to_resource(resource,
-					    ACPI_CAST_PTR(union aml_resource,
-							  aml),
-					    acpi_gbl_get_resource_dispatch
-					    [resource_index]);
+	    acpi_rs_convert_aml_to_resource(resource, aml_resource,
+					    conversion_table);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
 				"Could not convert AML resource (Type 0x%X)",
@@ -106,7 +131,7 @@
 
 	/* Point to the next structure in the output buffer */
 
-	*resource_ptr = ACPI_ADD_PTR(void, resource, resource->length);
+	*resource_ptr = ACPI_NEXT_RESOURCE(resource);
 	return_ACPI_STATUS(AE_OK);
 }
 
@@ -135,6 +160,7 @@
 {
 	u8 *aml = output_buffer;
 	u8 *end_aml = output_buffer + aml_size_needed;
+	struct acpi_rsconvert_info *conversion_table;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml);
@@ -154,11 +180,34 @@
 
 		/* Perform the conversion */
 
-		status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union
-										 aml_resource,
-										 aml),
-							 acpi_gbl_set_resource_dispatch
-							 [resource->type]);
+		if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
+			if (resource->data.common_serial_bus.type >
+			    AML_RESOURCE_MAX_SERIALBUSTYPE) {
+				conversion_table = NULL;
+			} else {
+				/* This is an I2C, SPI, or UART serial_bus descriptor */
+
+				conversion_table =
+				    acpi_gbl_convert_resource_serial_bus_dispatch
+				    [resource->data.common_serial_bus.type];
+			}
+		} else {
+			conversion_table =
+			    acpi_gbl_set_resource_dispatch[resource->type];
+		}
+
+		if (!conversion_table) {
+			ACPI_ERROR((AE_INFO,
+				    "Invalid/unsupported resource descriptor: Type 0x%2.2X",
+				    resource->type));
+			return (AE_AML_INVALID_RESOURCE_TYPE);
+		}
+
+		status = acpi_rs_convert_resource_to_aml(resource,
+						         ACPI_CAST_PTR(union
+								       aml_resource,
+								       aml),
+							 conversion_table);
 		if (ACPI_FAILURE(status)) {
 			ACPI_EXCEPTION((AE_INFO, status,
 					"Could not convert resource (type 0x%X) to AML",
@@ -192,9 +241,7 @@
 
 		/* Point to the next input resource descriptor */
 
-		resource =
-		    ACPI_ADD_PTR(struct acpi_resource, resource,
-				 resource->length);
+		resource = ACPI_NEXT_RESOURCE(resource);
 	}
 
 	/* Completed buffer, but did not find an end_tag resource descriptor */