diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2020-02-12 15:23:05 +0100 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2020-03-02 10:19:44 +0000 |
commit | e1498ce6da91c3e6bc61c67213f10ab927704510 (patch) | |
tree | c50a0b3d68878f0efd657dd0a503c36a2fc27e63 /src/superio/nuvoton/npcd378 | |
parent | 56626cf5d88523ed274c27e9624de7a358efe835 (diff) |
superio/nuvoton/npcd378: Switch to superio/common
Replace DSDT ACPI code and DSDT injection with a SSDT only solution.
The current implementation shows some issues on current Linux, which
might be due to external ACPI objects, which are then injected into
DSDT or the fact that those objects only use 3 characters.
Replace all the DSDT code with an SSDT generator.
Tested on HP Z220:
Boots into Linux with no ACPI errors. The SSDT can be disassembled.
Change-Id: I41616d9bf320fd2b4d8495892b8190cd2a2d057f
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38862
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Diffstat (limited to 'src/superio/nuvoton/npcd378')
-rw-r--r-- | src/superio/nuvoton/npcd378/Makefile.inc | 2 | ||||
-rw-r--r-- | src/superio/nuvoton/npcd378/acpi/superio.asl | 321 | ||||
-rw-r--r-- | src/superio/nuvoton/npcd378/superio.c | 373 |
3 files changed, 337 insertions, 359 deletions
diff --git a/src/superio/nuvoton/npcd378/Makefile.inc b/src/superio/nuvoton/npcd378/Makefile.inc index 6dc762605a..e70d69b0f0 100644 --- a/src/superio/nuvoton/npcd378/Makefile.inc +++ b/src/superio/nuvoton/npcd378/Makefile.inc @@ -2,3 +2,5 @@ # This file is part of the coreboot project. ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += superio.c +ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += ../../common/ssdt.c +ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += ../../common/generic.c diff --git a/src/superio/nuvoton/npcd378/acpi/superio.asl b/src/superio/nuvoton/npcd378/acpi/superio.asl index 41efb50b67..cffe33f9a8 100644 --- a/src/superio/nuvoton/npcd378/acpi/superio.asl +++ b/src/superio/nuvoton/npcd378/acpi/superio.asl @@ -1,321 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* This file is part of the coreboot project. */ -/* - * Include this file into a mainboard's DSDT _SB device tree and it will - * expose the NPCD378 SuperIO and some of its functionality. - * - * It allows the change of IO ports, IRQs and DMA settings on logical - * devices, disabling and reenabling logical devices. - * - * LDN State - * 0x2 SP1 Implemented, untested - * 0x5 KBCK Implemented, untested - */ - -#undef SUPERIO_CHIP_NAME -#define SUPERIO_CHIP_NAME NPCD378 -#include <superio/acpi/pnp.asl> - -#undef PNP_DEFAULT_PSC -#define PNP_DEFAULT_PSC Return (0) /* no power management */ - -Device(SUPERIO_DEV) { - Name (_HID, EisaId("PNP0A05")) - Name (_STR, Unicode("Nuvoton NPCD378 Super I/O")) - Name (_UID, SUPERIO_UID(SUPERIO_DEV,)) - - /* SuperIO configuration ports */ - OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02) - Field (CREG, ByteAcc, NoLock, Preserve) - { - PNP_ADDR_REG, 8, - PNP_DATA_REG, 8, - } - IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve) - { - Offset (0x07), - PNP_LOGICAL_DEVICE, 8, /* Logical device selector */ - - Offset (0x30), - PNP_DEVICE_ACTIVE, 1, /* Logical device activation */ - ACT1, 1, /* Logical device activation */ - ACT2, 1, /* Logical device activation */ - ACT3, 1, /* Logical device activation */ - ACT4, 1, /* Logical device activation */ - ACT5, 1, /* Logical device activation */ - ACT6, 1, /* Logical device activation */ - ACT7, 1, /* Logical device activation */ - - Offset (0x60), - PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */ - PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */ - Offset (0x62), - PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */ - PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */ - Offset (0x64), - PNP_IO2_HIGH_BYTE, 8, /* Third I/O port base - high byte */ - PNP_IO2_LOW_BYTE, 8, /* Third I/O port base - low byte */ - - Offset (0x70), - PNP_IRQ0, 8, /* First IRQ */ - Offset (0x72), - PNP_IRQ1, 8, /* Second IRQ */ - } - - #undef PNP_ENTER_MAGIC_1ST - #undef PNP_ENTER_MAGIC_2ND - #undef PNP_ENTER_MAGIC_3RD - #undef PNP_ENTER_MAGIC_4TH - #undef PNP_EXIT_MAGIC_1ST - #undef PNP_EXIT_SPECIAL_REG - #undef PNP_EXIT_SPECIAL_VAL - #define PNP_ENTER_MAGIC_1ST 0x87 - #define PNP_ENTER_MAGIC_2ND 0x87 - #define PNP_EXIT_MAGIC_1ST 0xaa - #include <superio/acpi/pnp_config.asl> - -#ifdef SUPERIO_SHOW_LPT - #undef SUPERIO_PNP_HID - #undef SUPERIO_PNP_LDN - #undef SUPERIO_PNP_DDN - #undef SUPERIO_PNP_PM_REG - #undef SUPERIO_PNP_PM_VAL - #undef SUPERIO_PNP_PM_LDN - #undef SUPERIO_PNP_IO0 - #undef SUPERIO_PNP_IO1 - #undef SUPERIO_PNP_IRQ0 - #undef SUPERIO_PNP_IRQ1 - #undef SUPERIO_PNP_DMA - #undef PNP_DEVICE_ACTIVE - #define PNP_DEVICE_ACTIVE ACT3 - #define SUPERIO_PNP_LDN 1 - #define SUPERIO_PNP_IO0 0x08, 0x08 - #include <superio/acpi/pnp_generic.asl> -#endif - -#ifdef SUPERIO_SHOW_SP1 - #undef SUPERIO_UART_LDN - #undef SUPERIO_UART_DDN - #undef SUPERIO_UART_PM_REG - #undef SUPERIO_UART_PM_VAL - #undef SUPERIO_UART_PM_LDN - #define SUPERIO_UART_LDN 2 - #include <superio/acpi/pnp_uart.asl> -#endif - -#ifdef SUPERIO_SHOW_SP2 - #undef SUPERIO_UART_LDN - #undef SUPERIO_UART_DDN - #undef SUPERIO_UART_PM_REG - #undef SUPERIO_UART_PM_VAL - #undef SUPERIO_UART_PM_LDN - #define SUPERIO_UART_LDN 3 - #include <superio/acpi/pnp_uart.asl> -#endif - -#ifdef SUPERIO_SHOW_KBC - #undef SUPERIO_KBC_LDN - #undef SUPERIO_KBC_PS2M - #undef SUPERIO_KBC_PS2LDN - #define SUPERIO_KBC_PS2LDN 5 - #define SUPERIO_KBC_LDN 6 - #include <superio/acpi/pnp_kbc.asl> -#endif - -#ifdef SUPERIO_SHOW_GPIO - #undef SUPERIO_PNP_HID - #undef SUPERIO_PNP_LDN - #undef SUPERIO_PNP_DDN - #undef SUPERIO_PNP_PM_REG - #undef SUPERIO_PNP_PM_VAL - #undef SUPERIO_PNP_PM_LDN - #undef SUPERIO_PNP_IO0 - #undef SUPERIO_PNP_IO1 - #undef SUPERIO_PNP_IO2 - #undef SUPERIO_PNP_IRQ0 - #undef SUPERIO_PNP_IRQ1 - #undef SUPERIO_PNP_DMA - #undef PNP_DEVICE_ACTIVE - #define PNP_DEVICE_ACTIVE ACT3 - #define SUPERIO_PNP_LDN 8 - #define SUPERIO_PNP_IO0 0x08, 0x08 - #include <superio/acpi/pnp_generic.asl> -#endif - - // generated by SSDT - External(SWB, IntObj) - External(SWL, IntObj) - OperationRegion (SWCR, SystemIO, SWB, SWL) - Field (SWCR, ByteAcc, NoLock, Preserve) - { - LEDC, 8, - SWCC, 8 - } - - // generated by SSDT - External(RNB, IntObj) - External(RNL, IntObj) - OperationRegion (RNTR, SystemIO, RNB, RNL) - Field (RNTR, ByteAcc, NoLock, Preserve) - { - GPES, 8, - GPEE, 8, - Offset (0x08), - GPS0, 8, - GPS1, 8, - GPS2, 8, - GPS3, 8, - GPE0, 8, - GPE1, 8, - GPE2, 8, - GPE3, 8 - } - - Name (MSFG, One) - Name (KBFG, One) - Name (PMFG, Zero) // Wake event backup - - Method (_CRS, 0, Serialized) - { - Name (CRS, ResourceTemplate () - { - FixedIO (SUPERIO_PNP_BASE, 0x02) - // filled below - FixedIO (0, 0, CRS1) - FixedIO (0, 0, CRS2) - }) - - CreateWordField (CRS, CRS1._BAS, TMP1) - Store(SWB, TMP1) - CreateByteField (CRS, CRS1._LEN, TMP2) - Store(SWL, TMP2) - - CreateWordField (CRS, CRS2._BAS, TMP3) - Store(RNB, TMP3) - CreateByteField (CRS, CRS2._LEN, TMP4) - Store(RNL, TMP4) - - /* Announce the used I/O ports to the OS */ - Return (CRS) - } - -#ifdef SUPERIO_SHOW_KBC - -#if defined(SUPERIO_KBC_LDN) -#define _PS2_KB SUPERIO_ID(KBD, SUPERIO_KBC_LDN) -#else -#define _PS2_KB PS2K -#endif - Scope (_PS2_KB) - { - Method (_PSW, 1, NotSerialized) - { - KBFG = Arg0 - } - - Method (_PRW, 0, NotSerialized) - { - Return (Package (0x02) {0x08, 0x03}) - } - } - -#if defined(SUPERIO_KBC_PS2M) -#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2M) -#elif defined(SUPERIO_KBC_PS2LDN) -#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN) -#else -#define _PS2_M PS2M -#endif - Scope (_PS2_M) - { - Method (_PSW, 1, NotSerialized) - { - MSFG = Arg0 - } - - Method (_PRW, 0, NotSerialized) - { - Return (Package (0x02) {0x08, 0x03}) - } - } - - Method (SIOH, 0, NotSerialized) - { - If ((PMFG & 0xE8)) - { - Notify (_PS2_KB, 0x02) - } - - If ((PMFG & 0x10)) - { - Notify (_PS2_M, 0x02) - } - } -#else - Method (SIOH, 0, NotSerialized) - { - } -#endif - - /* SuperIO sleep method */ - Method (SIOS, 1, NotSerialized) - { - If ((0x05 != Arg0)) - { - /* Set PS/2 powerstate in S3 */ - If (KBFG) - { - GPE2 |= 0xE8 - } - Else - { - GPE2 &= 0x17 - } - - If (MSFG) - { - GPE2 |= 0x10 - } - Else - { - GPE2 &= 0xEF - } - - /* Enable wake on GPE */ - GPEE = One - If ((0x03 == Arg0)) - { - /* green LED fading */ - Local1 = LEDC - Local1 &= 0xE0 - LEDC = (Local1 | 0x1C) - Local1 = SWCC - Local1 &= 0xBF - SWCC = (Local1 | 0x40) - } - } - - GPE0 = 0x10 - GPE1 = 0x20 - } - - /* SuperIO wake method */ - Method (SIOW, 1, NotSerialized) - { - /* Store wake status */ - PMFG = GPS2 - - /* Disable wake on GPE */ - GPEE = Zero - GPE0 = Zero - GPE1 = Zero - - /* green LED normal */ - Local1 = LEDC - Local1 &= 0xE0 - LEDC = (Local1 | 0x1E) - Local1 = SWCC - SWCC = (Local1 & 0xBF) - } -} +External (\_SB.PCI0.LPCB.SIO0, DeviceObj) +External (\_SB.PCI0.LPCB.SIO0.SIOS, MethodObj) +External (\_SB.PCI0.LPCB.SIO0.SIOW, MethodObj) diff --git a/src/superio/nuvoton/npcd378/superio.c b/src/superio/nuvoton/npcd378/superio.c index 624c1f0882..a07afdc79c 100644 --- a/src/superio/nuvoton/npcd378/superio.c +++ b/src/superio/nuvoton/npcd378/superio.c @@ -10,6 +10,8 @@ #include <superio/conf_mode.h> #include <arch/acpi.h> #include <arch/acpigen.h> +#include <superio/common/ssdt.h> +#include <stdlib.h> #include "npcd378.h" @@ -87,62 +89,351 @@ static void npcd378_init(struct device *dev) } #if CONFIG(HAVE_ACPI_TABLES) -static void npcd378_ssdt(struct device *dev) +/* Provide ACPI HIDs for generic Super I/O SSDT */ +static const char *npcd378_acpi_hid(const struct device *dev) { - struct resource *res; + /* Sanity checks */ + if (dev->path.type != DEVICE_PATH_PNP) + return NULL; + if (dev->path.pnp.port == 0) + return NULL; + if ((dev->path.pnp.device & 0xff) > NPCD378_GPIOA) + return NULL; - const char *scope = acpi_device_path(dev); - if (!scope) { - printk(BIOS_ERR, "%s: Missing ACPI scope\n", dev_path(dev)); - return; + switch (dev->path.pnp.device & 0xff) { + case NPCD378_FDC: + return ACPI_HID_FDC; + case NPCD378_PP: + return ACPI_HID_LPT; + case NPCD378_SP1: /* fallthrough */ + case NPCD378_SP2: + return ACPI_HID_COM; + case NPCD378_AUX: + return ACPI_HID_MOUSE; + case NPCD378_KBC: + return ACPI_HID_KEYBOARD; + default: + return ACPI_HID_PNP; } +} - switch (dev->path.pnp.device) { - case NPCD378_PWR: { - res = find_resource(dev, PNP_IDX_IO0); - if (!res || !res->base) { - printk(BIOS_ERR, "NPCD378: LDN%u IOBASE not set.\n", - NPCD378_PWR); - break; - } +static void npcd378_ssdt_aux(struct device *dev) +{ + /* Scope */ + acpigen_write_scope(acpi_device_path(dev)); - acpigen_write_scope(scope); - acpigen_write_name_integer("SWB", res->base); - acpigen_write_name_integer("SWL", res->size); - acpigen_pop_len(); /* pop scope */ + acpigen_write_method("_PSW", 1); + acpigen_write_store(); + acpigen_emit_byte(ARG0_OP); + acpigen_emit_namestring("^^MSFG"); + acpigen_pop_len(); /* Pop Method */ - res = find_resource(dev, PNP_IDX_IO1); - if (!res || !res->base) { - printk(BIOS_ERR, "NPCD378: LDN%u IOBASE2 not set.\n", - NPCD378_PWR); - break; - } + acpigen_write_PRW(8, 3); - acpigen_write_scope(scope); - acpigen_write_name_integer("RNB", res->base); - acpigen_write_name_integer("RNL", res->size); - acpigen_pop_len(); /* pop scope */ - break; - } - } + acpigen_pop_len(); /* Pop Scope */ +} + +static void npcd378_ssdt_kbc(struct device *dev) +{ + /* Scope */ + acpigen_write_scope(acpi_device_path(dev)); + + acpigen_write_method("_PSW", 1); + acpigen_write_store(); + acpigen_emit_byte(ARG0_OP); + acpigen_emit_namestring("^^KBFG"); + acpigen_pop_len(); /* Pop Method */ + + acpigen_write_PRW(8, 3); + + acpigen_pop_len(); /* Pop Scope */ +} + +static void npcd378_ssdt_pwr(struct device *dev) +{ + const char *name = acpi_device_path(dev); + const char *scope = acpi_device_scope(dev); + char *tmp_name; + + /* Scope */ + acpigen_write_scope(name); + + acpigen_emit_ext_op(OPREGION_OP); + acpigen_emit_namestring("SWCR"); + acpigen_emit_byte(SYSTEMIO); + acpigen_emit_namestring("IO0B"); + acpigen_emit_namestring("IO0S"); + + struct fieldlist l1[] = { + FIELDLIST_OFFSET(0), + FIELDLIST_NAMESTR("LEDC", 8), + FIELDLIST_NAMESTR("SWCC", 8), + }; + + acpigen_write_field("SWCR", l1, ARRAY_SIZE(l1), FIELD_BYTEACC | + FIELD_NOLOCK | FIELD_PRESERVE); + + acpigen_emit_ext_op(OPREGION_OP); + acpigen_emit_namestring("RNTR"); + acpigen_emit_byte(SYSTEMIO); + acpigen_emit_namestring("IO1B"); + acpigen_emit_namestring("IO1S"); + + struct fieldlist l2[] = { + FIELDLIST_OFFSET(0), + FIELDLIST_NAMESTR("GPES", 8), + FIELDLIST_NAMESTR("GPEE", 8), + FIELDLIST_OFFSET(8), + FIELDLIST_NAMESTR("GPS0", 8), + FIELDLIST_NAMESTR("GPS1", 8), + FIELDLIST_NAMESTR("GPS2", 8), + FIELDLIST_NAMESTR("GPS3", 8), + FIELDLIST_NAMESTR("GPE0", 8), + FIELDLIST_NAMESTR("GPE1", 8), + FIELDLIST_NAMESTR("GPE2", 8), + FIELDLIST_NAMESTR("GPE3", 8), + }; + + acpigen_write_field("RNTR", l2, ARRAY_SIZE(l2), FIELD_BYTEACC | + FIELD_NOLOCK | FIELD_PRESERVE); + + /* Method (SIOW, 1, NotSerialized) */ + acpigen_write_method("SIOW", 1); + acpigen_write_store(); + acpigen_emit_namestring("^GPS2"); + acpigen_emit_namestring("^^PMFG"); + + acpigen_write_store(); + acpigen_emit_byte(ZERO_OP); + acpigen_emit_namestring("^GPEE"); + + acpigen_write_store(); + acpigen_emit_byte(ZERO_OP); + acpigen_emit_namestring("^GPE0"); + + acpigen_write_store(); + acpigen_emit_byte(ZERO_OP); + acpigen_emit_namestring("^GPE1"); + + acpigen_emit_byte(AND_OP); + acpigen_emit_namestring("^LEDC"); + acpigen_write_integer(0xE0); + acpigen_emit_byte(LOCAL0_OP); + + acpigen_emit_byte(OR_OP); + acpigen_emit_byte(LOCAL0_OP); + acpigen_write_integer(0x1E); + acpigen_emit_namestring("^LEDC"); + + acpigen_emit_byte(AND_OP); + acpigen_emit_namestring("^SWCC"); + acpigen_write_integer(0xBF); + acpigen_emit_namestring("^SWCC"); + + acpigen_pop_len(); /* SIOW method */ + + /* Method (SIOS, 1, NotSerialized) */ + acpigen_write_method("SIOS", 1); + + acpigen_write_if(); + acpigen_emit_byte(LNOT_OP); + acpigen_emit_byte(LEQUAL_OP); + acpigen_emit_byte(ARG0_OP); + acpigen_write_integer(5); + + acpigen_write_if(); + acpigen_emit_byte(LEQUAL_OP); + acpigen_emit_namestring("^^KBFG"); + acpigen_emit_byte(ONE_OP); + + acpigen_emit_byte(OR_OP); + acpigen_emit_namestring("^GPE2"); + acpigen_write_integer(0xE8); + acpigen_emit_namestring("^GPE2"); + + acpigen_pop_len(); /* Pop If */ + acpigen_write_else(); + + acpigen_emit_byte(AND_OP); + acpigen_emit_namestring("^GPE2"); + acpigen_write_integer(0x17); + acpigen_emit_namestring("^GPE2"); + + acpigen_pop_len(); /* Pop Else */ + + acpigen_write_if(); + acpigen_emit_byte(LEQUAL_OP); + acpigen_emit_namestring("^^MSFG"); + acpigen_emit_byte(ONE_OP); + + acpigen_emit_byte(OR_OP); + acpigen_emit_namestring("^GPE2"); + acpigen_write_integer(0x10); + acpigen_emit_namestring("^GPE2"); + + acpigen_pop_len(); /* Pop If */ + acpigen_write_else(); + + acpigen_emit_byte(AND_OP); + acpigen_emit_namestring("^GPE2"); + acpigen_write_integer(0xEF); + acpigen_emit_namestring("^GPE2"); + + acpigen_pop_len(); /* Pop Else */ + + /* Enable wake on GPE */ + acpigen_write_store(); + acpigen_emit_byte(ONE_OP); + acpigen_emit_namestring("^GPEE"); + + acpigen_write_if(); + acpigen_emit_byte(LEQUAL_OP); + acpigen_emit_byte(ARG0_OP); + acpigen_write_integer(3); + + acpigen_emit_byte(AND_OP); + acpigen_emit_namestring("^LEDC"); + acpigen_write_integer(0xE0); + acpigen_emit_byte(LOCAL0_OP); + + acpigen_emit_byte(OR_OP); + acpigen_emit_byte(LOCAL0_OP); + acpigen_write_integer(0x1C); + acpigen_emit_namestring("^LEDC"); + + acpigen_emit_byte(AND_OP); + acpigen_emit_namestring("^SWCC"); + acpigen_write_integer(0xBF); + acpigen_emit_byte(LOCAL0_OP); + + acpigen_emit_byte(OR_OP); + acpigen_emit_byte(LOCAL0_OP); + acpigen_write_integer(0x40); + acpigen_emit_namestring("^SWCC"); + + acpigen_pop_len(); /* Pop If */ + + acpigen_pop_len(); /* Pop If */ + + acpigen_write_store(); + acpigen_write_integer(0x10); + acpigen_emit_namestring("^GPE0"); + + acpigen_write_store(); + acpigen_write_integer(0x20); + acpigen_emit_namestring("^GPE1"); + + acpigen_pop_len(); /* Pop SIOS method */ + + acpigen_pop_len(); /* Pop Scope */ + + /* Inject into parent: */ + acpigen_write_scope(acpi_device_scope(dev)); + + acpigen_write_name_integer("MSFG", 1); + acpigen_write_name_integer("KBFG", 1); + acpigen_write_name_integer("PMFG", 0); + + /* DSDT must call SIOW on _WAK */ + /* Method (SIOW, 1, NotSerialized) */ + acpigen_write_method("SIOW", 1); + acpigen_emit_byte(RETURN_OP); + tmp_name = strconcat(name, ".SIOW"); + acpigen_emit_namestring(tmp_name); + free(tmp_name); + + acpigen_emit_byte(ARG0_OP); + acpigen_pop_len(); + + /* DSDT must call SIOS on _PTS */ + /* Method (SIOS, 1, NotSerialized) */ + acpigen_write_method("SIOS", 1); + acpigen_emit_byte(RETURN_OP); + tmp_name = strconcat(name, ".SIOS"); + acpigen_emit_namestring(tmp_name); + free(tmp_name); + acpigen_emit_byte(ARG0_OP); + acpigen_pop_len(); /* Pop Method */ + + acpigen_pop_len(); /* Scope */ + + acpigen_write_scope("\\_GPE"); + + /* Method (SIOH, 0, NotSerialized) */ + acpigen_write_method("_L08", 0); + acpigen_emit_byte(AND_OP); + tmp_name = strconcat(scope, ".PMFG"); + acpigen_emit_namestring(tmp_name); + free(tmp_name); + acpigen_write_integer(0xE8); + acpigen_emit_byte(LOCAL0_OP); + + acpigen_write_if(); + acpigen_emit_byte(LGREATER_OP); + acpigen_emit_byte(LOCAL0_OP); + acpigen_emit_byte(ZERO_OP); + + acpigen_emit_byte(NOTIFY_OP); + tmp_name = strconcat(scope, ".L060"); + acpigen_emit_namestring(tmp_name); + free(tmp_name); + acpigen_write_integer(2); + + acpigen_pop_len(); /* Pop If */ + + acpigen_emit_byte(AND_OP); + tmp_name = strconcat(scope, ".PMFG"); + acpigen_emit_namestring(tmp_name); + free(tmp_name); + acpigen_write_integer(0x10); + acpigen_emit_byte(LOCAL0_OP); + + acpigen_write_if(); + acpigen_emit_byte(LGREATER_OP); + acpigen_emit_byte(LOCAL0_OP); + acpigen_emit_byte(ZERO_OP); + + acpigen_emit_byte(NOTIFY_OP); + tmp_name = strconcat(scope, ".L050"); + acpigen_emit_namestring(tmp_name); + free(tmp_name); + acpigen_write_integer(2); + acpigen_pop_len(); /* Pop If */ + + acpigen_pop_len(); /* Pop Method */ + + acpigen_pop_len(); /* Scope */ } -static const char *npcd378_acpi_name(const struct device *dev) +static void npcd378_fill_ssdt_generator(struct device *dev) { - return "SIO0"; + superio_common_fill_ssdt_generator(dev); + + switch (dev->path.pnp.device) { + case NPCD378_PWR: + npcd378_ssdt_pwr(dev); + break; + case NPCD378_AUX: + npcd378_ssdt_aux(dev); + break; + case NPCD378_KBC: + npcd378_ssdt_kbc(dev); + break; + } } #endif static struct device_operations ops = { - .read_resources = pnp_read_resources, - .set_resources = pnp_set_resources, - .enable_resources = pnp_enable_resources, - .enable = pnp_alt_enable, - .init = npcd378_init, - .ops_pnp_mode = &pnp_conf_mode_8787_aa, + .read_resources = pnp_read_resources, + .set_resources = pnp_set_resources, + .enable_resources = pnp_enable_resources, + .enable = pnp_alt_enable, + .init = npcd378_init, + .ops_pnp_mode = &pnp_conf_mode_8787_aa, #if CONFIG(HAVE_ACPI_TABLES) - .acpi_fill_ssdt_generator = npcd378_ssdt, - .acpi_name = npcd378_acpi_name, + .acpi_fill_ssdt_generator = npcd378_fill_ssdt_generator, + .acpi_name = superio_common_ldn_acpi_name, + .acpi_hid = npcd378_acpi_hid, #endif }; |