[PATCH] Naive implementation of AcpiExCmosSpaceHandler()
Anthony Jenkins
Anthony.B.Jenkins at att.net
Wed Jun 4 12:56:01 UTC 2014
Here's a naive implementation of AcpiExCmosSpaceHandler(), it simply uses I/O ports 0x70 and 0x71 to read/write CMOS registers using AcpiHwWritePort()/AcpiHwReadPort() calls. I'm new(ish) to the ACPICA subsystem and I'm probably not going about this the right way - I think I should implement an actual CMOS RTC device which handles the three PNP IDs that represent those hardware devices, but this was good enough for what I was trying to do.
This fixes my HP Envy 6z-1100 laptop's suspend/resume (except video fails to resume, but I believe that's due to backlight handling from my research). Before, initiating a suspend (zzz(8)) caused the laptop to seemingly suspend and immediately resume.
Now trying to track down the backlight issue. I implemented a missing _BQC method which returns a single value from the _BCL listj; I think Linux does some kind of vendor backlight control method if this method is missing.
Suggestions welcome.
Anthony Jenkins
Index: sys/contrib/dev/acpica/components/events/evhandler.c
===================================================================
--- sys/contrib/dev/acpica/components/events/evhandler.c (revision 266756)
+++ sys/contrib/dev/acpica/components/events/evhandler.c (working copy)
@@ -70,6 +70,7 @@
ACPI_ADR_SPACE_SYSTEM_MEMORY,
ACPI_ADR_SPACE_SYSTEM_IO,
ACPI_ADR_SPACE_PCI_CONFIG,
+ ACPI_ADR_SPACE_CMOS,
ACPI_ADR_SPACE_DATA_TABLE
};
@@ -379,9 +380,12 @@
*/
if ((Node->Type != ACPI_TYPE_DEVICE) &&
(Node->Type != ACPI_TYPE_PROCESSOR) &&
+ (Node->Type != ACPI_TYPE_REGION) &&
(Node->Type != ACPI_TYPE_THERMAL) &&
(Node != AcpiGbl_RootNode))
{
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Device %p not a DEVICE, PROCESSOR, REGION, THERMAL type or root node.\n", Node));
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
Index: sys/contrib/dev/acpica/components/executer/exregion.c
===================================================================
--- sys/contrib/dev/acpica/components/executer/exregion.c (revision 266756)
+++ sys/contrib/dev/acpica/components/executer/exregion.c (working copy)
@@ -449,7 +449,21 @@
return_ACPI_STATUS (Status);
}
+static UINT8 AcpiExCmosRead(ACPI_PHYSICAL_ADDRESS Address)
+{
+ UINT32 Value32;
+ AcpiHwWritePort((ACPI_IO_ADDRESS) 0x70, (UINT32) Address, 8);
+ AcpiHwReadPort ((ACPI_IO_ADDRESS) 0x71, &Value32, 8);
+ return Value32 & 0xFF;
+}
+
+static void AcpiExCmosWrite(ACPI_PHYSICAL_ADDRESS Address, UINT8 Value)
+{
+ AcpiHwWritePort((ACPI_IO_ADDRESS) 0x70, (UINT32) Address, 8);
+ AcpiHwWritePort((ACPI_IO_ADDRESS) 0x71, (UINT32) Value, 8);
+}
+
/*******************************************************************************
*
* FUNCTION: AcpiExCmosSpaceHandler
@@ -473,7 +487,7 @@
UINT32 Function,
ACPI_PHYSICAL_ADDRESS Address,
UINT32 BitWidth,
- UINT64 *Value,
+ UINT64 *Value64,
void *HandlerContext,
void *RegionContext)
{
@@ -482,7 +496,23 @@
ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
+ if (Address < 0x80 &&
+ (Function == ACPI_READ || Function == ACPI_WRITE) &&
+ BitWidth <= 64)
+ {
+ UINT32 i;
+ UINT8 *Value = (UINT8 *)Value64;
+ for (i = 0; i < (BitWidth + 7) / 8; ++i, ++Address, ++Value) {
+ if (Function == ACPI_READ) {
+ *Value = AcpiExCmosRead(Address);
+ } else {
+ AcpiExCmosWrite(Address, *Value);
+ }
+ }
+ } else {
+ Status = AE_BAD_PARAMETER;
+ }
return_ACPI_STATUS (Status);
}
Index: sys/contrib/dev/acpica/include/acconfig.h
===================================================================
--- sys/contrib/dev/acpica/include/acconfig.h (revision 266756)
+++ sys/contrib/dev/acpica/include/acconfig.h (working copy)
@@ -194,7 +194,7 @@
/* Maximum SpaceIds for Operation Regions */
#define ACPI_MAX_ADDRESS_SPACE 255
-#define ACPI_NUM_DEFAULT_SPACES 4
+#define ACPI_NUM_DEFAULT_SPACES 5
/* Array sizes. Used for range checking also */
More information about the freebsd-acpi
mailing list