From 5501d02e635c3839c5cbb3a4f86b8ae8c00c25f0 Mon Sep 17 00:00:00 2001 From: qzed Date: Sun, 28 Oct 2018 14:11:10 +0100 Subject: [PATCH] add patches required by acpi-notify module --- ...CPI-Fix-buffer-integer-type-mismatch.patch | 58 ++++++++ ...sbus-write-transaction-buffer-length.patch | 37 +++++ ...d-ACPI-clients-by-ResourceSource-tag.patch | 138 ++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 patches/4.18/0101-ACPI-Fix-buffer-integer-type-mismatch.patch create mode 100644 patches/4.18/0102-ACPI-Fix-gsbus-write-transaction-buffer-length.patch create mode 100644 patches/4.18/0103-serdev-Find-ACPI-clients-by-ResourceSource-tag.patch diff --git a/patches/4.18/0101-ACPI-Fix-buffer-integer-type-mismatch.patch b/patches/4.18/0101-ACPI-Fix-buffer-integer-type-mismatch.patch new file mode 100644 index 000000000..82c63c0f3 --- /dev/null +++ b/patches/4.18/0101-ACPI-Fix-buffer-integer-type-mismatch.patch @@ -0,0 +1,58 @@ +From 902cc2930c358a6306a0204e4087edb37ab3f3bd Mon Sep 17 00:00:00 2001 +From: qzed +Date: Thu, 20 Sep 2018 00:23:49 +0200 +Subject: [PATCH] ACPI: Fix buffer/integer type mismatch + +--- + drivers/acpi/acpica/dsopcode.c | 2 +- + drivers/acpi/acpica/exfield.c | 12 +++++++++--- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c +index e9fb0bf3c8d2..cad7d94fa8d8 100644 +--- a/drivers/acpi/acpica/dsopcode.c ++++ b/drivers/acpi/acpica/dsopcode.c +@@ -123,7 +123,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, + + /* Offset is in bits, count is in bits */ + +- field_flags = AML_FIELD_ACCESS_BYTE; ++ field_flags = AML_FIELD_ACCESS_BUFFER; + bit_offset = offset; + bit_count = (u32) length_desc->integer.value; + +diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c +index b272c329d45d..e75e84091617 100644 +--- a/drivers/acpi/acpica/exfield.c ++++ b/drivers/acpi/acpica/exfield.c +@@ -102,6 +102,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, + void *buffer; + u32 function; + u16 accessor_type; ++ u8 field_flags; + + ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); + +@@ -199,11 +200,16 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, + * Note: Field.length is in bits. + */ + length = +- (acpi_size)ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length); ++ (acpi_size)ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length); ++ field_flags = obj_desc->common_field.field_flags; + +- if (length > acpi_gbl_integer_byte_width) { ++ if (length > acpi_gbl_integer_byte_width || ++ (field_flags & AML_FIELD_ACCESS_TYPE_MASK) == AML_FIELD_ACCESS_BUFFER) { + +- /* Field is too large for an Integer, create a Buffer instead */ ++ /* ++ * Field is either too large for an Integer, or a actually of type ++ * buffer, so create a Buffer. ++ */ + + buffer_desc = acpi_ut_create_buffer_object(length); + if (!buffer_desc) { +-- +2.19.0 + diff --git a/patches/4.18/0102-ACPI-Fix-gsbus-write-transaction-buffer-length.patch b/patches/4.18/0102-ACPI-Fix-gsbus-write-transaction-buffer-length.patch new file mode 100644 index 000000000..1cbfde600 --- /dev/null +++ b/patches/4.18/0102-ACPI-Fix-gsbus-write-transaction-buffer-length.patch @@ -0,0 +1,37 @@ +From 7a8233faf6364605bd6a2f2ca7f597db3e535084 Mon Sep 17 00:00:00 2001 +From: qzed +Date: Thu, 20 Sep 2018 00:29:50 +0200 +Subject: [PATCH] ACPI: Fix gsbus write transaction buffer length + +--- + drivers/acpi/acpica/exfield.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c +index e75e84091617..cf547883a993 100644 +--- a/drivers/acpi/acpica/exfield.c ++++ b/drivers/acpi/acpica/exfield.c +@@ -372,19 +372,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, + } else if (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_GSBUS) { + accessor_type = obj_desc->field.attribute; +- length = +- acpi_ex_get_serial_access_length(accessor_type, +- obj_desc->field. +- access_length); +- +- /* +- * Add additional 2 bytes for the generic_serial_bus data buffer: +- * +- * Status; (Byte 0 of the data buffer) +- * Length; (Byte 1 of the data buffer) +- * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) +- */ +- length += 2; ++ length = source_desc->buffer.length; + function = ACPI_WRITE | (accessor_type << 16); + } else { /* IPMI */ + +-- +2.19.0 + diff --git a/patches/4.18/0103-serdev-Find-ACPI-clients-by-ResourceSource-tag.patch b/patches/4.18/0103-serdev-Find-ACPI-clients-by-ResourceSource-tag.patch new file mode 100644 index 000000000..859ab5d3f --- /dev/null +++ b/patches/4.18/0103-serdev-Find-ACPI-clients-by-ResourceSource-tag.patch @@ -0,0 +1,138 @@ +From 7ce2363e61250c09dad42c6bd305312166e5b6f7 Mon Sep 17 00:00:00 2001 +From: qzed +Date: Wed, 10 Oct 2018 15:17:35 +0200 +Subject: [PATCH] serdev: Find ACPI clients by ResourceSource tag + +If serdev can't find ACPI clients directly under the controller node, +search for (UART) devices in the whole ACPI tree by matching the +ResourceSource tag of the corresponding resource descriptor to the +controller's path. +--- + drivers/tty/serdev/core.c | 90 ++++++++++++++++++++++++++++++++++++++- + 1 file changed, 88 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c +index 9e59f4788589..d9f4700722b6 100644 +--- a/drivers/tty/serdev/core.c ++++ b/drivers/tty/serdev/core.c +@@ -466,8 +466,7 @@ static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl, + struct serdev_device *serdev = NULL; + int err; + +- if (acpi_bus_get_status(adev) || !adev->status.present || +- acpi_device_enumerated(adev)) ++ if (acpi_bus_get_status(adev) || !adev->status.present) + return AE_OK; + + serdev = serdev_device_alloc(ctrl); +@@ -490,6 +489,81 @@ static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl, + return AE_OK; + } + ++struct acpi_serdev_add_device_from_resource_ctx { ++ acpi_handle ctrl_handle; ++ acpi_handle device_handle; ++ struct serdev_controller *ctrl; ++ struct acpi_device *device; ++}; ++ ++static acpi_status ++acpi_serdev_add_device_from_resource(struct acpi_resource *resource, void *data) ++{ ++ struct acpi_serdev_add_device_from_resource_ctx* ctx = data; ++ struct acpi_resource_source *ctrl_name; ++ acpi_handle ctrl_handle; ++ acpi_status status; ++ ++ if (resource->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) ++ return AE_OK; ++ ++ if (resource->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) ++ return AE_OK; ++ ++ ctrl_name = &resource->data.common_serial_bus.resource_source; ++ if (ctrl_name->string_length == 0 || !ctrl_name->string_ptr) { ++ return AE_OK; ++ } ++ ++ status = acpi_get_handle(ctx->device_handle, ctrl_name->string_ptr, ++ &ctrl_handle); ++ if (ACPI_FAILURE(status)) { ++ return AE_OK; ++ } ++ ++ if (ctrl_handle == ctx->ctrl_handle) { ++ return acpi_serdev_register_device(ctx->ctrl, ctx->device); ++ } ++ ++ return AE_OK; ++} ++ ++static acpi_status ++acpi_serdev_add_devices_from_resources(acpi_handle handle, u32 level, ++ void *data, void **return_value) ++{ ++ struct acpi_serdev_add_device_from_resource_ctx *ctx = data; ++ acpi_status status; ++ ++ ctx->device_handle = handle; ++ ++ status = acpi_bus_get_device(handle, &ctx->device); ++ if (status) return AE_OK; ++ ++ status = acpi_walk_resources(handle, METHOD_NAME__CRS, ++ acpi_serdev_add_device_from_resource, ++ ctx); ++ ++ if (status == AE_NOT_FOUND) ++ return AE_OK; // not finding _CRS is not an error ++ else ++ return status; ++} ++ ++static int ++acpi_serdev_register_devices_from_resources(acpi_handle handle, ++ struct serdev_controller *ctrl) ++{ ++ struct acpi_serdev_add_device_from_resource_ctx ctx = { ++ .ctrl = ctrl, ++ .ctrl_handle = handle, ++ }; ++ ++ return acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 128, ++ acpi_serdev_add_devices_from_resources, ++ NULL, &ctx, NULL); ++} ++ + static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, + void *data, void **return_value) + { +@@ -499,6 +573,9 @@ static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level, + if (acpi_bus_get_device(handle, &adev)) + return AE_OK; + ++ if (acpi_device_enumerated(adev)) ++ return AE_OK; ++ + return acpi_serdev_register_device(ctrl, adev); + } + +@@ -516,6 +593,15 @@ static int acpi_serdev_register_devices(struct serdev_controller *ctrl) + if (ACPI_FAILURE(status)) + dev_dbg(&ctrl->dev, "failed to enumerate serdev slaves\n"); + ++ if (!ctrl->serdev) { ++ status = acpi_serdev_register_devices_from_resources(handle, ctrl); ++ if (ACPI_FAILURE(status)) { ++ dev_dbg(&ctrl->dev, ++ "failed to register serdev slaves from resources: %x\n", ++ status); ++ } ++ } ++ + if (!ctrl->serdev) + return -ENODEV; + +-- +2.19.1 +