soc/intel: hook up new gpio device in the soc chips

This change adds the required gpio operations struct to soc/common gpio
code and hooks them up in all socs currently using the gpio block code,
except DNV-NS, which is handled in a separate change.

Also, add the gpio device to existing chipset devicetrees.

Successfully tested on Supermicro X11SSM-F with CB:48097, X11SSH-TF with
CB:48711 and OCP DeltaLake with CB:48672.

Change-Id: I81dbbf5397b28ffa7537465c53332779245b39f6
Tested-by: Johnny Lin <Johnny_Lin@wiwynn.com>
Tested-by: Michael Niewöhner <foss@mniewoehner.de>
Tested-by: Patrick Rudolph <siro@das-labor.org>
Signed-off-by: Michael Niewöhner <foss@mniewoehner.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/48583
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/intel/alderlake/chip.c b/src/soc/intel/alderlake/chip.c
index 794c3ba..95b6b8f 100644
--- a/src/soc/intel/alderlake/chip.c
+++ b/src/soc/intel/alderlake/chip.c
@@ -6,6 +6,7 @@
 #include <fsp/util.h>
 #include <intelblocks/acpi.h>
 #include <intelblocks/cfg.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
 #include <intelblocks/xdci.h>
@@ -182,6 +183,8 @@
 	else if (dev->path.type == DEVICE_PATH_PCI &&
 		 dev->path.pci.devfn == PCH_DEVFN_PMC)
 		dev->ops = &pmc_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 struct chip_operations soc_intel_alderlake_ops = {
diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb
index de97a57..173d3e0 100644
--- a/src/soc/intel/alderlake/chipset.cb
+++ b/src/soc/intel/alderlake/chipset.cb
@@ -1,5 +1,6 @@
 chip soc/intel/alderlake
 	device domain 0 on
+		device gpio 0 alias pch_gpio on end
 		device pci 00.0 alias system_agent on end
 		device pci 01.0 alias pcie5 off end
 		device pci 02.0 alias igpu off end
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c
index a4ed8bdc..fdbeef2 100644
--- a/src/soc/intel/apollolake/chip.c
+++ b/src/soc/intel/apollolake/chip.c
@@ -19,6 +19,7 @@
 #include <fsp/api.h>
 #include <fsp/util.h>
 #include <intelblocks/cpulib.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pmclib.h>
 #include <romstage_handoff.h>
@@ -216,6 +217,8 @@
 		dev->ops = &pci_domain_ops;
 	else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
 		dev->ops = &cpu_bus_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 /*
diff --git a/src/soc/intel/cannonlake/chip.c b/src/soc/intel/cannonlake/chip.c
index 1769846..0958aac 100644
--- a/src/soc/intel/cannonlake/chip.c
+++ b/src/soc/intel/cannonlake/chip.c
@@ -6,6 +6,7 @@
 #include <fsp/util.h>
 #include <intelblocks/acpi.h>
 #include <intelblocks/cfg.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
 #include <intelblocks/xdci.h>
@@ -209,6 +210,8 @@
 		dev->ops = &pci_domain_ops;
 	else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
 		dev->ops = &cpu_bus_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 struct chip_operations soc_intel_cannonlake_ops = {
diff --git a/src/soc/intel/common/block/gpio/Makefile.inc b/src/soc/intel/common/block/gpio/Makefile.inc
index b0ffee3..0379e92 100644
--- a/src/soc/intel/common/block/gpio/Makefile.inc
+++ b/src/soc/intel/common/block/gpio/Makefile.inc
@@ -3,3 +3,5 @@
 romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += gpio.c
 smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += gpio.c
 verstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += gpio.c
+
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += gpio_dev.c
diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c
index fb9287c..28e78fb 100644
--- a/src/soc/intel/common/block/gpio/gpio.c
+++ b/src/soc/intel/common/block/gpio/gpio.c
@@ -2,6 +2,7 @@
 
 #include <assert.h>
 #include <console/console.h>
+#include <device/device.h>
 #include <intelblocks/gpio.h>
 #include <gpio.h>
 #include <intelblocks/itss.h>
diff --git a/src/soc/intel/common/block/gpio/gpio_dev.c b/src/soc/intel/common/block/gpio/gpio_dev.c
new file mode 100644
index 0000000..c47d3a2
--- /dev/null
+++ b/src/soc/intel/common/block/gpio/gpio_dev.c
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <assert.h>
+#include <device/device.h>
+#include <device/gpio.h>
+#include <intelblocks/gpio.h>
+#include <gpio.h>
+
+static struct gpio_operations gpio_ops = {
+	.get		= gpio_get,
+	.set		= gpio_set,
+	.input_pulldown	= gpio_input_pulldown,
+	.input_pullup	= gpio_input_pullup,
+	.input		= gpio_input,
+	.output		= gpio_output,
+};
+
+static struct device_operations block_gpio_ops = {
+	.read_resources	= noop_read_resources,
+	.set_resources	= noop_set_resources,
+	.ops_gpio	= &gpio_ops,
+};
+
+void block_gpio_enable(struct device *dev)
+{
+	assert(dev->path.type == DEVICE_PATH_GPIO);
+	dev->ops = &block_gpio_ops;
+}
diff --git a/src/soc/intel/common/block/include/intelblocks/gpio.h b/src/soc/intel/common/block/include/intelblocks/gpio.h
index 173a383..4c29a0c 100644
--- a/src/soc/intel/common/block/include/intelblocks/gpio.h
+++ b/src/soc/intel/common/block/include/intelblocks/gpio.h
@@ -25,6 +25,7 @@
 
 #ifndef __ACPI__
 #include <types.h>
+#include <device/device.h>
 
 /*
  * GPIO numbers may not be contiguous and instead will have a different
@@ -222,5 +223,11 @@
 /* The function performs GPIO Power Management programming. */
 void gpio_pm_configure(const uint8_t *misccfg_pm_values, size_t num);
 
+/*
+ * Set gpio ops of the device to gpio block ops.
+ * Shall be called by all SoCs that use intelblocks/gpio.
+ */
+void block_gpio_enable(struct device *dev);
+
 #endif
 #endif /* _SOC_INTELBLOCKS_GPIO_H_ */
diff --git a/src/soc/intel/elkhartlake/chip.c b/src/soc/intel/elkhartlake/chip.c
index 8b4cf0c..359aa11 100644
--- a/src/soc/intel/elkhartlake/chip.c
+++ b/src/soc/intel/elkhartlake/chip.c
@@ -6,6 +6,7 @@
 #include <fsp/util.h>
 #include <intelblocks/acpi.h>
 #include <intelblocks/cfg.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
 #include <intelblocks/xdci.h>
@@ -163,6 +164,8 @@
 	else if (dev->path.type == DEVICE_PATH_PCI &&
 		 dev->path.pci.devfn == PCH_DEVFN_PMC)
 		dev->ops = &pmc_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 struct chip_operations soc_intel_elkhartlake_ops = {
diff --git a/src/soc/intel/icelake/chip.c b/src/soc/intel/icelake/chip.c
index d0ea732..d493f81 100644
--- a/src/soc/intel/icelake/chip.c
+++ b/src/soc/intel/icelake/chip.c
@@ -6,6 +6,7 @@
 #include <fsp/util.h>
 #include <intelblocks/acpi.h>
 #include <intelblocks/cfg.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/xdci.h>
 #include <romstage_handoff.h>
@@ -144,6 +145,8 @@
 		dev->ops = &pci_domain_ops;
 	else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
 		dev->ops = &cpu_bus_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 struct chip_operations soc_intel_icelake_ops = {
diff --git a/src/soc/intel/icelake/chip.h b/src/soc/intel/icelake/chip.h
index cd0a9b0..64bc70b 100644
--- a/src/soc/intel/icelake/chip.h
+++ b/src/soc/intel/icelake/chip.h
@@ -9,6 +9,7 @@
 #include <intelblocks/gspi.h>
 #include <stdint.h>
 #include <soc/gpe.h>
+#include <soc/gpio.h>
 #include <soc/pch.h>
 #include <soc/gpio_defs.h>
 #include <soc/pci_devs.h>
diff --git a/src/soc/intel/jasperlake/chip.c b/src/soc/intel/jasperlake/chip.c
index d34ef55..1f58f84c 100644
--- a/src/soc/intel/jasperlake/chip.c
+++ b/src/soc/intel/jasperlake/chip.c
@@ -6,6 +6,7 @@
 #include <fsp/util.h>
 #include <intelblocks/acpi.h>
 #include <intelblocks/cfg.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
 #include <intelblocks/xdci.h>
@@ -169,6 +170,8 @@
 	else if (dev->path.type == DEVICE_PATH_PCI &&
 		 dev->path.pci.devfn == PCH_DEVFN_PMC)
 		dev->ops = &pmc_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 struct chip_operations soc_intel_jasperlake_ops = {
diff --git a/src/soc/intel/jasperlake/chip.h b/src/soc/intel/jasperlake/chip.h
index 9d4bc5c..884071f 100644
--- a/src/soc/intel/jasperlake/chip.h
+++ b/src/soc/intel/jasperlake/chip.h
@@ -9,6 +9,7 @@
 #include <intelblocks/gspi.h>
 #include <intelblocks/power_limit.h>
 #include <soc/gpe.h>
+#include <soc/gpio.h>
 #include <soc/pch.h>
 #include <soc/pci_devs.h>
 #include <soc/pmc.h>
diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c
index 2707353..5b05dd2 100644
--- a/src/soc/intel/skylake/chip.c
+++ b/src/soc/intel/skylake/chip.c
@@ -7,6 +7,7 @@
 #include <device/device.h>
 #include <device/pci_ids.h>
 #include <fsp/util.h>
+#include <gpio.h>
 #include <intelblocks/cfg.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/lpc_lib.h>
@@ -103,6 +104,8 @@
 		dev->ops = &pci_domain_ops;
 	else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
 		dev->ops = &cpu_bus_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 struct chip_operations soc_intel_skylake_ops = {
diff --git a/src/soc/intel/skylake/chipset.cb b/src/soc/intel/skylake/chipset.cb
index 28ee53d..428db67 100644
--- a/src/soc/intel/skylake/chipset.cb
+++ b/src/soc/intel/skylake/chipset.cb
@@ -1,5 +1,6 @@
 chip soc/intel/skylake
 	device domain 0 on
+		device gpio 0 alias pch_gpio       on  end # GPIO
 		device pci 00.0 alias system_agent on  end # Host Bridge
 		device pci 01.0 alias peg0         off end # PEG0
 		device pci 01.1 alias peg1         off end # PEG1
diff --git a/src/soc/intel/tigerlake/chip.c b/src/soc/intel/tigerlake/chip.c
index 62201a2..f07cc58 100644
--- a/src/soc/intel/tigerlake/chip.c
+++ b/src/soc/intel/tigerlake/chip.c
@@ -7,6 +7,7 @@
 #include <fsp/util.h>
 #include <intelblocks/acpi.h>
 #include <intelblocks/cfg.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
 #include <intelblocks/xdci.h>
@@ -177,6 +178,8 @@
 	else if (dev->path.type == DEVICE_PATH_PCI &&
 		 dev->path.pci.devfn == PCH_DEVFN_PMC)
 		dev->ops = &pmc_ops;
+	else if (dev->path.type == DEVICE_PATH_GPIO)
+		block_gpio_enable(dev);
 }
 
 struct chip_operations soc_intel_tigerlake_ops = {
diff --git a/src/soc/intel/tigerlake/chip.h b/src/soc/intel/tigerlake/chip.h
index fe10d0d..f38330b 100644
--- a/src/soc/intel/tigerlake/chip.h
+++ b/src/soc/intel/tigerlake/chip.h
@@ -9,6 +9,7 @@
 #include <intelblocks/gspi.h>
 #include <intelblocks/power_limit.h>
 #include <soc/gpe.h>
+#include <soc/gpio.h>
 #include <soc/pch.h>
 #include <soc/pci_devs.h>
 #include <soc/pmc.h>
diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb
index 54f7924..d4bc76c 100644
--- a/src/soc/intel/tigerlake/chipset.cb
+++ b/src/soc/intel/tigerlake/chipset.cb
@@ -1,5 +1,6 @@
 chip soc/intel/tigerlake
 	device domain 0 on
+		device gpio 0 alias pch_gpio on end
 		device pci 00.0 alias system_agent on end
 		device pci 02.0 alias igpu off end
 		device pci 04.0 alias dptf off end
diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c
index a3076a8..778d277 100644
--- a/src/soc/intel/xeon_sp/cpx/chip.c
+++ b/src/soc/intel/xeon_sp/cpx/chip.c
@@ -5,6 +5,7 @@
 #include <console/debug.h>
 #include <cpu/x86/lapic.h>
 #include <device/pci.h>
+#include <intelblocks/gpio.h>
 #include <intelblocks/lpc_lib.h>
 #include <intelblocks/p2sb.h>
 #include <soc/acpi.h>
@@ -61,6 +62,8 @@
 		attach_iio_stacks(dev);
 	} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
 		dev->ops = &cpu_bus_ops;
+	} else if (dev->path.type == DEVICE_PATH_GPIO) {
+		block_gpio_enable(dev);
 	}
 }
 
diff --git a/src/soc/intel/xeon_sp/cpx/chip.h b/src/soc/intel/xeon_sp/cpx/chip.h
index 434b343..630bc8e 100644
--- a/src/soc/intel/xeon_sp/cpx/chip.h
+++ b/src/soc/intel/xeon_sp/cpx/chip.h
@@ -4,6 +4,7 @@
 #define _SOC_CHIP_H_
 
 #include <intelblocks/cfg.h>
+#include <soc/gpio.h>
 #include <soc/irq.h>
 #include <stdint.h>
 
diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c
index f101973..8b08326 100644
--- a/src/soc/intel/xeon_sp/skx/chip.c
+++ b/src/soc/intel/xeon_sp/skx/chip.c
@@ -3,6 +3,7 @@
 #include <cbfs.h>
 #include <console/console.h>
 #include <device/pci.h>
+#include <intelblocks/gpio.h>
 #include <soc/acpi.h>
 #include <soc/chip_common.h>
 #include <soc/pch.h>
@@ -37,6 +38,8 @@
 		attach_iio_stacks(dev);
 	} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
 		dev->ops = &cpu_bus_ops;
+	} else if (dev->path.type == DEVICE_PATH_GPIO) {
+		block_gpio_enable(dev);
 	}
 }
 
diff --git a/src/soc/intel/xeon_sp/skx/chip.h b/src/soc/intel/xeon_sp/skx/chip.h
index 0860899..4ee1ac0 100644
--- a/src/soc/intel/xeon_sp/skx/chip.h
+++ b/src/soc/intel/xeon_sp/skx/chip.h
@@ -5,6 +5,7 @@
 
 #include <stdint.h>
 #include <intelblocks/cfg.h>
+#include <soc/gpio.h>
 #include <soc/irq.h>
 
 struct soc_intel_xeon_sp_skx_config {