summaryrefslogtreecommitdiff
path: root/source/components/executer
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2014-09-29 19:53:38 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2014-09-29 19:53:38 +0000
commitd4e301bc21b6911ed7f5d6a86659c4882fa7ab55 (patch)
treec09826b28ca0b50455664fa1d18a4efff33181e4 /source/components/executer
parent754171ae60abbbd707ed8d449f07ef38f596bd22 (diff)
Notes
Diffstat (limited to 'source/components/executer')
-rw-r--r--source/components/executer/exfield.c68
-rw-r--r--source/components/executer/exprep.c2
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) &&