diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2014-09-29 19:53:38 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2014-09-29 19:53:38 +0000 |
commit | d4e301bc21b6911ed7f5d6a86659c4882fa7ab55 (patch) | |
tree | c09826b28ca0b50455664fa1d18a4efff33181e4 /source/components/executer | |
parent | 754171ae60abbbd707ed8d449f07ef38f596bd22 (diff) |
Notes
Diffstat (limited to 'source/components/executer')
-rw-r--r-- | source/components/executer/exfield.c | 68 | ||||
-rw-r--r-- | source/components/executer/exprep.c | 2 |
2 files changed, 70 insertions, 0 deletions
diff --git a/source/components/executer/exfield.c b/source/components/executer/exfield.c index 49d3b667b78e8..65520b651ca43 100644 --- a/source/components/executer/exfield.c +++ b/source/components/executer/exfield.c @@ -273,6 +273,39 @@ AcpiExReadDataFromField ( Buffer = &BufferDesc->Integer.Value; } + if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && + (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) + { + /* + * For GPIO (GeneralPurposeIo), the Address will be the bit offset + * from the previous Connection() operator, making it effectively a + * pin number index. The BitLength is the length of the field, which + * is thus the number of pins. + */ + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "GPIO FieldRead [FROM]: Pin %u Bits %u\n", + ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength)); + + /* Lock entire transaction if requested */ + + AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); + + /* Perform the write */ + + Status = AcpiExAccessRegion (ObjDesc, 0, + (UINT64 *) Buffer, ACPI_READ); + AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); + if (ACPI_FAILURE (Status)) + { + AcpiUtRemoveReference (BufferDesc); + } + else + { + *RetBufferDesc = BufferDesc; + } + return_ACPI_STATUS (Status); + } + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n", ObjDesc, ObjDesc->Common.Type, Buffer, (UINT32) Length)); @@ -446,6 +479,41 @@ AcpiExWriteDataToField ( *ResultDesc = BufferDesc; return_ACPI_STATUS (Status); } + else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && + (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) + { + /* + * For GPIO (GeneralPurposeIo), we will bypass the entire field + * mechanism and handoff the bit address and bit width directly to + * the handler. The Address will be the bit offset + * from the previous Connection() operator, making it effectively a + * pin number index. The BitLength is the length of the field, which + * is thus the number of pins. + */ + if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER) + { + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + } + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n", + AcpiUtGetTypeName (SourceDesc->Common.Type), + SourceDesc->Common.Type, (UINT32) SourceDesc->Integer.Value, + ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength)); + + Buffer = &SourceDesc->Integer.Value; + + /* Lock entire transaction if requested */ + + AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); + + /* Perform the write */ + + Status = AcpiExAccessRegion (ObjDesc, 0, + (UINT64 *) Buffer, ACPI_WRITE); + AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); + return_ACPI_STATUS (Status); + } /* Get a pointer to the data to be written */ diff --git a/source/components/executer/exprep.c b/source/components/executer/exprep.c index 77ccb87ce1170..89dcd041cf9c5 100644 --- a/source/components/executer/exprep.c +++ b/source/components/executer/exprep.c @@ -515,6 +515,8 @@ AcpiExPrepFieldValue ( ObjDesc->Field.ResourceLength = Info->ResourceLength; } + ObjDesc->Field.PinNumberIndex = Info->PinNumberIndex; + /* Allow full data read from EC address space */ if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) && |