diff --git a/src/superio/nuvoton/nct5104d/nct5104d.h b/src/superio/nuvoton/nct5104d/nct5104d.h index 9a881059c0..3f78c1d0d4 100644 --- a/src/superio/nuvoton/nct5104d/nct5104d.h +++ b/src/superio/nuvoton/nct5104d/nct5104d.h @@ -40,7 +40,6 @@ #define NCT5104D_FDC 0x00 /* FDC - not pinned out */ #define NCT5104D_SP1 0x02 /* UARTA */ #define NCT5104D_SP2 0x03 /* UARTB */ -#define NCT5104D_GPIO_WDT 0x08 /* GPIO WDT Interface */ #define NCT5104D_GPIO_PP_OD 0x0F /* GPIO Push-Pull / Open drain select */ #define NCT5104D_SP3 0x10 /* UARTC */ #define NCT5104D_SP4 0x11 /* UARTD */ @@ -48,6 +47,7 @@ /* Virtual Logical Device Numbers (LDN) */ #define NCT5104D_GPIO_V 0x07 /* GPIO - 0,1,6 Interface */ +#define NCT5104D_GPIO_WDT_V 0x08 /* GPIO/WDT Interface */ /* Virtual devices sharing the enables are encoded as follows: VLDN = baseLDN[7:0] | [10:8] bitpos of enable in 0x30 of baseLDN @@ -56,6 +56,9 @@ #define NCT5104D_GPIO1 ((1 << 8) | NCT5104D_GPIO_V) #define NCT5104D_GPIO6 ((6 << 8) | NCT5104D_GPIO_V) +#define NCT5104D_GPIO_WDT ((0 << 8) | NCT5104D_GPIO_WDT_V) +#define NCT5104D_GPIO_IO ((1 << 8) | NCT5104D_GPIO_WDT_V) + void nct5104d_enable_uartd(pnp_devfn_t dev); #endif /* SUPERIO_NUVOTON_NCT5104D_H */ diff --git a/src/superio/nuvoton/nct5104d/superio.c b/src/superio/nuvoton/nct5104d/superio.c index 69f54a731f..6836d695c0 100644 --- a/src/superio/nuvoton/nct5104d/superio.c +++ b/src/superio/nuvoton/nct5104d/superio.c @@ -14,7 +14,9 @@ * GNU General Public License for more details. */ +#include #include +#include #include #include "nct5104d.h" @@ -147,6 +149,29 @@ static void reset_gpio_default_od(struct device *dev) pnp_write_config(dev, NCT5104D_GPIO6_PP_OD, 0xFF); } +static void disable_gpio_io_port(struct device *dev) +{ + struct device *gpio0, *gpio1, *gpio6; + + /* + * Since UARTC and UARTD share pins with GPIO0 and GPIO1 and the + * GPIO/UART can be selected via Kconfig, check whether at least one of + * GPIOs is enabled and if yes keep the GPIO IO VLDN enabled. If no + * GPIOs are enabled, disable the VLDN in order to protect from invalid + * devicetree + Kconfig settings. + */ + gpio0 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO0); + gpio1 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO1); + gpio6 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO6); + + if (!((gpio0 && gpio0->enabled) || (gpio1 && gpio1->enabled) || + (gpio6 && gpio6->enabled))) { + dev->enabled = 0; + printk(BIOS_WARNING, "WARNING: GPIO IO port configured," + " but no GPIO enabled. Disabling..."); + } +} + static void nct5104d_init(struct device *dev) { struct superio_nuvoton_nct5104d_config *conf = dev->chip_info; @@ -177,6 +202,9 @@ static void nct5104d_init(struct device *dev) case NCT5104D_GPIO_PP_OD: reset_gpio_default_od(dev); break; + case NCT5104D_GPIO_IO: + disable_gpio_io_port(dev); + break; default: break; } @@ -204,6 +232,7 @@ static struct pnp_info pnp_dev_info[] = { { NULL, NCT5104D_GPIO1}, { NULL, NCT5104D_GPIO6}, { NULL, NCT5104D_GPIO_PP_OD}, + { NULL, NCT5104D_GPIO_IO, PNP_IO0, 0x07f8, }, { NULL, NCT5104D_PORT80}, };