summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch762
1 files changed, 0 insertions, 762 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch
deleted file mode 100644
index c409dec50..000000000
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch
+++ /dev/null
@@ -1,762 +0,0 @@
-From e6e186acacc16fd95251b2d0fb024993a66ffa0a Mon Sep 17 00:00:00 2001
-From: Haiyue Wang <haiyue.wang@linux.intel.com>
-Date: Sat, 24 Feb 2018 11:12:32 +0800
-Subject: [PATCH] Add AST2500 eSPI driver
-
-When PCH works under eSPI mode, the PMC (Power Management Controller) in
-PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in
-dead loop if no SUS_ACK assert. This is the basic requirement for the BMC
-works as eSPI slave.
-
-Also for the host power on / off actions, from BMC side, the following VW
-(Virtual Wire) messages are done in firmware:
-1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
-2. SUS_ACK
-3. OOB_RESET_ACK
-4. HOST_RESET_ACK
-
-Also, it provides monitoring interface of PLTRST_N signal through
-/dev/espi-pltrstn
-
-Signed-off-by: Haiyue Wang <haiyue.wang@linux.intel.com>
-Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
-Signed-off-by: James Feist <james.feist@linux.intel.com>
-Signed-off-by: Vernon Mauery <vernon.mauery@intel.com>
----
- .../devicetree/bindings/misc/aspeed,espi-slave.txt | 20 +
- Documentation/misc-devices/espi-slave.rst | 118 ++++++
- arch/arm/boot/dts/aspeed-g5.dtsi | 4 +
- arch/arm/boot/dts/aspeed-g6.dtsi | 14 +
- drivers/misc/Kconfig | 8 +
- drivers/misc/Makefile | 1 +
- drivers/misc/aspeed-espi-slave.c | 468 +++++++++++++++++++++
- include/dt-bindings/clock/ast2600-clock.h | 1 +
- 8 files changed, 634 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/misc/aspeed,espi-slave.txt
- create mode 100644 Documentation/misc-devices/espi-slave.rst
- create mode 100644 drivers/misc/aspeed-espi-slave.c
-
-diff --git a/Documentation/devicetree/bindings/misc/aspeed,espi-slave.txt b/Documentation/devicetree/bindings/misc/aspeed,espi-slave.txt
-new file mode 100644
-index 000000000000..f72d9ae32f3e
---- /dev/null
-+++ b/Documentation/devicetree/bindings/misc/aspeed,espi-slave.txt
-@@ -0,0 +1,20 @@
-+ASPEED eSPI Slave Controller
-+
-+Required properties:
-+ - compatible: must be one of:
-+ - "aspeed,ast2500-espi-slave"
-+ - "aspeed,ast2600-espi-slave"
-+
-+ - reg: physical base address of the controller and length of memory mapped
-+ region
-+
-+ - interrupts: interrupt generated by the controller
-+
-+Example:
-+
-+ espi: espi@1e6ee000 {
-+ compatible = "aspeed,ast2500-espi-slave";
-+ reg = <0x1e6ee000 0x100>;
-+ interrupts = <23>;
-+ status = "disabled";
-+};
-diff --git a/Documentation/misc-devices/espi-slave.rst b/Documentation/misc-devices/espi-slave.rst
-new file mode 100644
-index 000000000000..887a69a7130a
---- /dev/null
-+++ b/Documentation/misc-devices/espi-slave.rst
-@@ -0,0 +1,118 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+
-+==========
-+eSPI Slave
-+==========
-+
-+:Author: Haiyue Wang <haiyue.wang@linux.intel.com>
-+
-+The PCH (**eSPI master**) provides the eSPI to support connection of a
-+BMC (**eSPI slave**) to the platform.
-+
-+The LPC and eSPI interfaces are mutually exclusive. Both use the same
-+pins, but on power-up, a HW strap determines if the eSPI or the LPC bus
-+is operational. Once selected, it’s not possible to change to the other
-+interface.
-+
-+``eSPI Channels and Supported Transactions``
-+ +------+---------------------+----------------------+--------------------+
-+ | CH # | Channel | Posted Cycles | Non-Posted Cycles |
-+ +======+=====================+======================+====================+
-+ | 0 | Peripheral | Memory Write, | Memory Read, |
-+ | | | Completions | I/O Read/Write |
-+ +------+---------------------+----------------------+--------------------+
-+ | 1 | Virtual Wire | Virtual Wire GET/PUT | N/A |
-+ +------+---------------------+----------------------+--------------------+
-+ | 2 | Out-of-Band Message | SMBus Packet GET/PUT | N/A |
-+ +------+---------------------+----------------------+--------------------+
-+ | 3 | Flash Access | N/A | Flash Read, Write, |
-+ | | | | Erase |
-+ +------+---------------------+----------------------+--------------------+
-+ | N/A | General | Register Accesses | N/A |
-+ +------+---------------------+----------------------+--------------------+
-+
-+Virtual Wire Channel (Channel 1) Overview
-+-----------------------------------------
-+
-+The Virtual Wire channel uses a standard message format to communicate
-+several types of signals between the components on the platform::
-+
-+ - Sideband and GPIO Pins: System events and other dedicated signals
-+ between the PCH and eSPI slave. These signals are tunneled between the
-+ two components over eSPI.
-+
-+ - Serial IRQ Interrupts: Interrupts are tunneled from the eSPI slave to
-+ the PCH. Both edge and triggered interrupts are supported.
-+
-+When PCH runs on eSPI mode, from BMC side, the following VW messages are
-+done in firmware::
-+
-+ 1. SLAVE_BOOT_LOAD_DONE / SLAVE_BOOT_LOAD_STATUS
-+ 2. SUS_ACK
-+ 3. OOB_RESET_ACK
-+ 4. HOST_RESET_ACK
-+
-+``eSPI Virtual Wires (VW)``
-+ +----------------------+---------+---------------------------------------+
-+ |Virtual Wire |PCH Pin |Comments |
-+ | |Direction| |
-+ +======================+=========+=======================================+
-+ |SUS_WARN# |Output |PCH pin is a GPIO when eSPI is enabled.|
-+ | | |eSPI controller receives as VW message.|
-+ +----------------------+---------+---------------------------------------+
-+ |SUS_ACK# |Input |PCH pin is a GPIO when eSPI is enabled.|
-+ | | |eSPI controller receives as VW message.|
-+ +----------------------+---------+---------------------------------------+
-+ |SLAVE_BOOT_LOAD_DONE |Input |Sent when the BMC has completed its |
-+ | | |boot process as an indication to |
-+ | | |eSPI-MC to continue with the G3 to S0 |
-+ | | |exit. |
-+ | | |The eSPI Master waits for the assertion|
-+ | | |of this virtual wire before proceeding |
-+ | | |with the SLP_S5# deassertion. |
-+ | | |The intent is that it is never changed |
-+ | | |except on a G3 exit - it is reset on a |
-+ | | |G3 entry. |
-+ +----------------------+---------+---------------------------------------+
-+ |SLAVE_BOOT_LOAD_STATUS|Input |Sent upon completion of the Slave Boot |
-+ | | |Load from the attached flash. A stat of|
-+ | | |1 indicates that the boot code load was|
-+ | | |successful and that the integrity of |
-+ | | |the image is intact. |
-+ +----------------------+---------+---------------------------------------+
-+ |HOST_RESET_WARN |Output |Sent from the MC just before the Host |
-+ | | |is about to enter reset. Upon receiving|
-+ | | |, the BMC must flush and quiesce its |
-+ | | |upstream Peripheral Channel request |
-+ | | |queues and assert HOST_RESET_ACK VWire.|
-+ | | |The MC subsequently completes any |
-+ | | |outstanding posted transactions or |
-+ | | |completions and then disables the |
-+ | | |Peripheral Channel via a write to |
-+ | | |the Slave's Configuration Register. |
-+ +----------------------+---------+---------------------------------------+
-+ |HOST_RESET_ACK |Input |ACK for the HOST_RESET_WARN message |
-+ +----------------------+---------+---------------------------------------+
-+ |OOB_RESET_WARN |Output |Sent from the MC just before the OOB |
-+ | | |processor is about to enter reset. Upon|
-+ | | |receiving, the BMC must flush and |
-+ | | |quiesce its OOB Channel upstream |
-+ | | |request queues and assert OOB_RESET_ACK|
-+ | | |VWire. The-MC subsequently completes |
-+ | | |any outstanding posted transactions or |
-+ | | |completions and then disables the OOB |
-+ | | |Channel via a write to the Slave's |
-+ | | |Configuration Register. |
-+ +----------------------+---------+---------------------------------------+
-+ |OOB_RESET_ACK |Input |ACK for OOB_RESET_WARN message |
-+ +----------------------+---------+---------------------------------------+
-+
-+`Intel C620 Series Chipset Platform Controller Hub
-+<https://www.intel.com/content/www/us/en/chipsets/c620-series-chipset-datasheet.html>`_
-+
-+ -- 17. Enhanced Serial Peripheral Interface
-+
-+
-+`Enhanced Serial Peripheral Interface (eSPI)
-+- Interface Base Specification (for Client and Server Platforms)
-+<https://www.intel.com/content/dam/support/us/en/documents/software/chipset-software/327432-004_espi_base_specification_rev1.0.pdf>`_
-diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
-index 26d885d2bd8a..7b798c49cb95 100644
---- a/arch/arm/boot/dts/aspeed-g5.dtsi
-+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
-@@ -336,6 +336,7 @@
- clocks = <&syscon ASPEED_CLK_APB>;
- interrupt-controller;
- #interrupt-cells = <2>;
-+ status = "disabled";
- };
-
- sgpio: sgpio@1e780200 {
-@@ -432,6 +433,9 @@
- reg = <0x1e6ee000 0x100>;
- interrupts = <23>;
- status = "disabled";
-+ clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinctrl_espi_default>;
- };
-
- lpc: lpc@1e789000 {
-diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
-index 825e64ce317a..315d35c15208 100644
---- a/arch/arm/boot/dts/aspeed-g6.dtsi
-+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
-@@ -4,6 +4,7 @@
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/clock/ast2600-clock.h>
- #include <dt-bindings/interrupt-controller/aspeed-scu-ic.h>
-+#include <dt-bindings/gpio/aspeed-gpio.h>
-
- / {
- model = "Aspeed BMC";
-@@ -708,6 +709,19 @@
- status = "disabled";
- };
-
-+ espi: espi@1e6ee000 {
-+ compatible = "aspeed,ast2600-espi-slave";
-+ reg = <0x1e6ee000 0x200>;
-+ interrupts-extended = <&gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
-+ <&gpio0 ASPEED_GPIO(W, 7) IRQ_TYPE_EDGE_FALLING>;
-+ status = "disabled";
-+ clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
-+ resets = <&syscon ASPEED_RESET_ESPI>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinctrl_espi_default>,
-+ <&pinctrl_espialt_default>;
-+ };
-+
- i2c: bus@1e78a000 {
- compatible = "simple-bus";
- #address-cells = <1>;
-diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
-index 06a2b753cc7c..0f9b5a356c93 100644
---- a/drivers/misc/Kconfig
-+++ b/drivers/misc/Kconfig
-@@ -433,6 +433,14 @@ config VEXPRESS_SYSCFG
- bus. System Configuration interface is one of the possible means
- of generating transactions on this bus.
-
-+config ASPEED_ESPI_SLAVE
-+ depends on ARCH_ASPEED || COMPILE_TEST
-+ depends on REGMAP_MMIO
-+ tristate "Aspeed ast2500 eSPI slave device driver"
-+ ---help---
-+ Control Aspeed ast2500 eSPI slave controller to handle event
-+ which needs the firmware's processing.
-+
- config PCI_ENDPOINT_TEST
- depends on PCI
- select CRC32
-diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
-index b9e6d4c3e906..53864687e8fd 100644
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -51,6 +51,7 @@ obj-$(CONFIG_GENWQE) += genwqe/
- obj-$(CONFIG_ECHO) += echo/
- obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
- obj-$(CONFIG_CXL_BASE) += cxl/
-+obj-$(CONFIG_ASPEED_ESPI_SLAVE) += aspeed-espi-slave.o
- obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
- obj-$(CONFIG_OCXL) += ocxl/
- obj-y += cardreader/
-diff --git a/drivers/misc/aspeed-espi-slave.c b/drivers/misc/aspeed-espi-slave.c
-new file mode 100644
-index 000000000000..87bc81948694
---- /dev/null
-+++ b/drivers/misc/aspeed-espi-slave.c
-@@ -0,0 +1,468 @@
-+// SPDX-License-Identifier: GPL-2.0
-+// Copyright (c) 2015-2019, Intel Corporation.
-+
-+#include <linux/clk.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/miscdevice.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/sched/signal.h>
-+#include <linux/spinlock.h>
-+#include <linux/uaccess.h>
-+
-+#define ASPEED_ESPI_CTRL 0x00
-+#define ASPEED_ESPI_CTRL_SW_RESET GENMASK(31, 24)
-+#define ASPEED_ESPI_CTRL_OOB_CHRDY BIT(4)
-+#define ASPEED_ESPI_INT_STS 0x08
-+#define ASPEED_ESPI_HW_RESET BIT(31)
-+#define ASPEED_ESPI_VW_SYSEVT1 BIT(22)
-+#define ASPEED_ESPI_VW_SYSEVT BIT(8)
-+#define ASPEED_ESPI_INT_EN 0x0C
-+#define ASPEED_ESPI_DATA_PORT 0x28
-+#define ASPEED_ESPI_SYSEVT_INT_EN 0x94
-+#define ASPEED_ESPI_SYSEVT 0x98
-+#define ASPEED_ESPI_SYSEVT_HOST_RST_ACK BIT(27)
-+#define ASPEED_ESPI_SYSEVT_SLAVE_BOOT_STATUS BIT(23)
-+#define ASPEED_ESPI_SYSEVT_SLAVE_BOOT_DONE BIT(20)
-+#define ASPEED_ESPI_SYSEVT_OOB_RST_ACK BIT(16)
-+#define ASPEED_ESPI_SYSEVT_INT_T0 0x110
-+#define ASPEED_ESPI_SYSEVT_INT_T1 0x114
-+#define ASPEED_ESPI_SYSEVT_INT_T2 0x118
-+#define ASPEED_ESPI_SYSEVT_INT_STS 0x11C
-+#define ASPEED_ESPI_SYSEVT_HOST_RST_WARN BIT(8)
-+#define ASPEED_ESPI_SYSEVT_OOB_RST_WARN BIT(6)
-+#define ASPEED_ESPI_SYSEVT_PLTRSTN BIT(5)
-+#define ASPEED_ESPI_SYSEVT1_INT_EN 0x100
-+#define ASPEED_ESPI_SYSEVT1 0x104
-+#define ASPEED_ESPI_SYSEVT1_SUS_ACK BIT(20)
-+#define ASPEED_ESPI_SYSEVT1_INT_T0 0x120
-+#define ASPEED_ESPI_SYSEVT1_INT_T1 0x124
-+#define ASPEED_ESPI_SYSEVT1_INT_T2 0x128
-+#define ASPEED_ESPI_SYSEVT1_INT_STS 0x12C
-+#define ASPEED_ESPI_SYSEVT1_SUS_WARN BIT(0)
-+
-+#define ASPEED_ESPI_INT_MASK \
-+ (ASPEED_ESPI_HW_RESET | \
-+ ASPEED_ESPI_VW_SYSEVT1 | \
-+ ASPEED_ESPI_VW_SYSEVT)
-+
-+/*
-+ * Setup Interrupt Type / Enable of System Event from Master
-+ * T2 T1 T0
-+ * 1) HOST_RST_WARN : Dual Edge 1 0 0
-+ * 2) OOB_RST_WARN : Dual Edge 1 0 0
-+ * 3) PLTRSTN : Dual Edge 1 0 0
-+ */
-+#define ASPEED_ESPI_SYSEVT_INT_T0_MASK 0
-+#define ASPEED_ESPI_SYSEVT_INT_T1_MASK 0
-+#define ASPEED_ESPI_SYSEVT_INT_T2_MASK \
-+ (ASPEED_ESPI_SYSEVT_HOST_RST_WARN | \
-+ ASPEED_ESPI_SYSEVT_OOB_RST_WARN | \
-+ ASPEED_ESPI_SYSEVT_PLTRSTN)
-+#define ASPEED_ESPI_SYSEVT_INT_MASK \
-+ (ASPEED_ESPI_SYSEVT_INT_T0_MASK | \
-+ ASPEED_ESPI_SYSEVT_INT_T1_MASK | \
-+ ASPEED_ESPI_SYSEVT_INT_T2_MASK)
-+
-+/*
-+ * Setup Interrupt Type / Enable of System Event 1 from Master
-+ * T2 T1 T0
-+ * 1) SUS_WARN : Rising Edge 0 0 1
-+ */
-+#define ASPEED_ESPI_SYSEVT1_INT_T0_MASK ASPEED_ESPI_SYSEVT1_SUS_WARN
-+#define ASPEED_ESPI_SYSEVT1_INT_T1_MASK 0
-+#define ASPEED_ESPI_SYSEVT1_INT_T2_MASK 0
-+#define ASPEED_ESPI_SYSEVT1_INT_MASK \
-+ (ASPEED_ESPI_SYSEVT1_INT_T0_MASK | \
-+ ASPEED_ESPI_SYSEVT1_INT_T1_MASK | \
-+ ASPEED_ESPI_SYSEVT1_INT_T2_MASK)
-+
-+struct aspeed_espi {
-+ struct regmap *map;
-+ struct clk *clk;
-+ struct device *dev;
-+ struct reset_control *reset;
-+ int irq;
-+ int rst_irq;
-+
-+ /* for PLTRST_N signal monitoring interface */
-+ struct miscdevice pltrstn_miscdev;
-+ spinlock_t pltrstn_lock; /* for PLTRST_N signal sampling */
-+ wait_queue_head_t pltrstn_waitq;
-+ char pltrstn;
-+};
-+
-+static void aspeed_espi_sys_event(struct aspeed_espi *priv)
-+{
-+ u32 sts, evt;
-+
-+ regmap_read(priv->map, ASPEED_ESPI_SYSEVT_INT_STS, &sts);
-+ regmap_read(priv->map, ASPEED_ESPI_SYSEVT, &evt);
-+
-+ dev_dbg(priv->dev, "sys: sts = %08x, evt = %08x\n", sts, evt);
-+
-+ if (!(evt & ASPEED_ESPI_SYSEVT_SLAVE_BOOT_STATUS)) {
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT,
-+ evt | ASPEED_ESPI_SYSEVT_SLAVE_BOOT_STATUS |
-+ ASPEED_ESPI_SYSEVT_SLAVE_BOOT_DONE);
-+ dev_dbg(priv->dev, "Setting espi slave boot done\n");
-+ }
-+ if (sts & ASPEED_ESPI_SYSEVT_HOST_RST_WARN &&
-+ evt & ASPEED_ESPI_SYSEVT_HOST_RST_WARN) {
-+ regmap_write_bits(priv->map, ASPEED_ESPI_SYSEVT,
-+ ASPEED_ESPI_SYSEVT_HOST_RST_ACK,
-+ ASPEED_ESPI_SYSEVT_HOST_RST_ACK);
-+ dev_dbg(priv->dev, "SYSEVT_HOST_RST_WARN: acked\n");
-+ }
-+ if (sts & ASPEED_ESPI_SYSEVT_OOB_RST_WARN &&
-+ evt & ASPEED_ESPI_SYSEVT_OOB_RST_WARN) {
-+ regmap_write_bits(priv->map, ASPEED_ESPI_SYSEVT,
-+ ASPEED_ESPI_SYSEVT_OOB_RST_ACK,
-+ ASPEED_ESPI_SYSEVT_OOB_RST_ACK);
-+ dev_dbg(priv->dev, "SYSEVT_OOB_RST_WARN: acked\n");
-+ }
-+ if (sts & ASPEED_ESPI_SYSEVT_PLTRSTN || priv->pltrstn == 'U') {
-+ priv->pltrstn = (evt & ASPEED_ESPI_SYSEVT_PLTRSTN) ? '1' : '0';
-+ wake_up_interruptible(&priv->pltrstn_waitq);
-+ dev_dbg(priv->dev, "SYSEVT_PLTRSTN: %c\n", priv->pltrstn);
-+ }
-+
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT_INT_STS, sts);
-+}
-+
-+static void aspeed_espi_sys_event1(struct aspeed_espi *priv)
-+{
-+ u32 sts, evt;
-+
-+ regmap_read(priv->map, ASPEED_ESPI_SYSEVT1_INT_STS, &sts);
-+ regmap_read(priv->map, ASPEED_ESPI_SYSEVT1, &evt);
-+
-+ dev_dbg(priv->dev, "sys event1: sts = %08x, evt = %08x\n", sts, evt);
-+
-+ if (sts & ASPEED_ESPI_SYSEVT1_SUS_WARN &&
-+ evt & ASPEED_ESPI_SYSEVT1_SUS_WARN) {
-+ regmap_write_bits(priv->map, ASPEED_ESPI_SYSEVT1,
-+ ASPEED_ESPI_SYSEVT1_SUS_ACK,
-+ ASPEED_ESPI_SYSEVT1_SUS_ACK);
-+ dev_dbg(priv->dev, "SYSEVT1_SUS_WARN: acked\n");
-+ }
-+
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT1_INT_STS, sts);
-+}
-+
-+static void aspeed_espi_boot_ack(struct aspeed_espi *priv)
-+{
-+ u32 evt;
-+
-+ regmap_read(priv->map, ASPEED_ESPI_SYSEVT, &evt);
-+ if (!(evt & ASPEED_ESPI_SYSEVT_SLAVE_BOOT_STATUS)) {
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT,
-+ evt | ASPEED_ESPI_SYSEVT_SLAVE_BOOT_STATUS |
-+ ASPEED_ESPI_SYSEVT_SLAVE_BOOT_DONE);
-+ dev_dbg(priv->dev, "Setting espi slave boot done\n");
-+ }
-+
-+ regmap_read(priv->map, ASPEED_ESPI_SYSEVT1, &evt);
-+ if (evt & ASPEED_ESPI_SYSEVT1_SUS_WARN &&
-+ !(evt & ASPEED_ESPI_SYSEVT1_SUS_ACK)) {
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT1,
-+ evt | ASPEED_ESPI_SYSEVT1_SUS_ACK);
-+ dev_dbg(priv->dev, "Boot SYSEVT1_SUS_WARN: acked\n");
-+ }
-+}
-+
-+static irqreturn_t aspeed_espi_irq(int irq, void *arg)
-+{
-+ struct aspeed_espi *priv = arg;
-+ u32 sts, sts_handled = 0;
-+
-+ regmap_read(priv->map, ASPEED_ESPI_INT_STS, &sts);
-+
-+ dev_dbg(priv->dev, "INT_STS: 0x%08x\n", sts);
-+
-+ if (sts & ASPEED_ESPI_VW_SYSEVT) {
-+ aspeed_espi_sys_event(priv);
-+ sts_handled |= ASPEED_ESPI_VW_SYSEVT;
-+ }
-+
-+ if (sts & ASPEED_ESPI_VW_SYSEVT1) {
-+ aspeed_espi_sys_event1(priv);
-+ sts_handled |= ASPEED_ESPI_VW_SYSEVT1;
-+ }
-+
-+ if (sts & ASPEED_ESPI_HW_RESET) {
-+ if (priv->rst_irq < 0) {
-+ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL,
-+ ASPEED_ESPI_CTRL_SW_RESET, 0);
-+ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL,
-+ ASPEED_ESPI_CTRL_SW_RESET,
-+ ASPEED_ESPI_CTRL_SW_RESET);
-+ }
-+
-+ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL,
-+ ASPEED_ESPI_CTRL_OOB_CHRDY,
-+ ASPEED_ESPI_CTRL_OOB_CHRDY);
-+ aspeed_espi_boot_ack(priv);
-+ sts_handled |= ASPEED_ESPI_HW_RESET;
-+ }
-+
-+ regmap_write(priv->map, ASPEED_ESPI_INT_STS, sts);
-+
-+ return sts != sts_handled ? IRQ_NONE : IRQ_HANDLED;
-+}
-+
-+static void aspeed_espi_config_irq(struct aspeed_espi *priv)
-+{
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT_INT_T0,
-+ ASPEED_ESPI_SYSEVT_INT_T0_MASK);
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT_INT_T1,
-+ ASPEED_ESPI_SYSEVT_INT_T1_MASK);
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT_INT_T2,
-+ ASPEED_ESPI_SYSEVT_INT_T2_MASK);
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT_INT_EN,
-+ ASPEED_ESPI_SYSEVT_INT_MASK);
-+
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT1_INT_T0,
-+ ASPEED_ESPI_SYSEVT1_INT_T0_MASK);
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT1_INT_T1,
-+ ASPEED_ESPI_SYSEVT1_INT_T1_MASK);
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT1_INT_T2,
-+ ASPEED_ESPI_SYSEVT1_INT_T2_MASK);
-+ regmap_write(priv->map, ASPEED_ESPI_SYSEVT1_INT_EN,
-+ ASPEED_ESPI_SYSEVT1_INT_MASK);
-+
-+ regmap_write(priv->map, ASPEED_ESPI_INT_EN, ASPEED_ESPI_INT_MASK);
-+}
-+
-+static irqreturn_t aspeed_espi_reset_isr(int irq, void *arg)
-+{
-+ struct aspeed_espi *priv = arg;
-+
-+ reset_control_assert(priv->reset);
-+ reset_control_deassert(priv->reset);
-+
-+ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL,
-+ ASPEED_ESPI_CTRL_SW_RESET, 0);
-+ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL,
-+ ASPEED_ESPI_CTRL_SW_RESET, ASPEED_ESPI_CTRL_SW_RESET);
-+
-+ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL,
-+ ASPEED_ESPI_CTRL_OOB_CHRDY, 0);
-+
-+ aspeed_espi_config_irq(priv);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static inline struct aspeed_espi *to_aspeed_espi(struct file *filp)
-+{
-+ return container_of(filp->private_data, struct aspeed_espi,
-+ pltrstn_miscdev);
-+}
-+
-+static int aspeed_espi_pltrstn_open(struct inode *inode, struct file *filp)
-+{
-+ if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
-+ return -EACCES;
-+
-+ return 0;
-+}
-+
-+static ssize_t aspeed_espi_pltrstn_read(struct file *filp, char __user *buf,
-+ size_t count, loff_t *offset)
-+{
-+ struct aspeed_espi *priv = to_aspeed_espi(filp);
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long flags;
-+ char old_sample;
-+ int ret = 0;
-+
-+ spin_lock_irqsave(&priv->pltrstn_lock, flags);
-+
-+ add_wait_queue(&priv->pltrstn_waitq, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ old_sample = priv->pltrstn;
-+
-+ do {
-+ char new_sample = priv->pltrstn;
-+
-+ if (filp->f_flags & O_NONBLOCK || old_sample != new_sample) {
-+ ret = put_user(new_sample, (unsigned long __user *)buf);
-+ if (!ret)
-+ ret = sizeof(new_sample);
-+ } else if (signal_pending(current)) {
-+ ret = -ERESTARTSYS;
-+ }
-+
-+ if (!ret) {
-+ spin_unlock_irqrestore(&priv->pltrstn_lock, flags);
-+ schedule();
-+ spin_lock_irqsave(&priv->pltrstn_lock, flags);
-+ }
-+ } while (!ret);
-+
-+ remove_wait_queue(&priv->pltrstn_waitq, &wait);
-+ set_current_state(TASK_RUNNING);
-+
-+ spin_unlock_irqrestore(&priv->pltrstn_lock, flags);
-+
-+ return ret;
-+}
-+
-+static const struct file_operations aspeed_espi_pltrstn_fops = {
-+ .owner = THIS_MODULE,
-+ .open = aspeed_espi_pltrstn_open,
-+ .read = aspeed_espi_pltrstn_read,
-+};
-+
-+static const struct regmap_config aspeed_espi_regmap_cfg = {
-+ .reg_bits = 32,
-+ .reg_stride = 4,
-+ .val_bits = 32,
-+ .max_register = ASPEED_ESPI_SYSEVT1_INT_STS,
-+};
-+
-+static int aspeed_espi_probe(struct platform_device *pdev)
-+{
-+ struct aspeed_espi *priv;
-+ struct resource *res;
-+ void __iomem *regs;
-+ u32 ctrl;
-+ int ret;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ regs = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(regs))
-+ return PTR_ERR(regs);
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ dev_set_drvdata(&pdev->dev, priv);
-+ priv->dev = &pdev->dev;
-+
-+ priv->map = devm_regmap_init_mmio(&pdev->dev, regs,
-+ &aspeed_espi_regmap_cfg);
-+ if (IS_ERR(priv->map))
-+ return PTR_ERR(priv->map);
-+
-+ spin_lock_init(&priv->pltrstn_lock);
-+ init_waitqueue_head(&priv->pltrstn_waitq);
-+ priv->pltrstn = 'U'; /* means it's not reported yet from master */
-+
-+ priv->irq = platform_get_irq(pdev, 0);
-+ if (priv->irq < 0)
-+ return priv->irq;
-+
-+ ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_espi_irq, 0,
-+ "aspeed-espi-irq", priv);
-+ if (ret)
-+ return ret;
-+
-+ if (of_device_is_compatible(pdev->dev.of_node,
-+ "aspeed,ast2600-espi-slave")) {
-+ priv->rst_irq = platform_get_irq(pdev, 1);
-+ if (priv->rst_irq < 0)
-+ return priv->rst_irq;
-+
-+ ret = devm_request_irq(&pdev->dev, priv->rst_irq,
-+ aspeed_espi_reset_isr, 0,
-+ "aspeed-espi-rst-irq", priv);
-+ if (ret)
-+ return ret;
-+
-+ priv->reset = devm_reset_control_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->reset))
-+ return PTR_ERR(priv->reset);
-+ } else {
-+ priv->rst_irq = -ENOTSUPP;
-+ }
-+
-+ priv->clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->clk)) {
-+ ret = PTR_ERR(priv->clk);
-+ if (ret != -EPROBE_DEFER)
-+ dev_err(&pdev->dev, "couldn't get clock\n");
-+ return ret;
-+ }
-+ ret = clk_prepare_enable(priv->clk);
-+ if (ret) {
-+ dev_err(&pdev->dev, "couldn't enable clock\n");
-+ return ret;
-+ }
-+
-+ /*
-+ * We check that the regmap works on this very first access, but as this
-+ * is an MMIO-backed regmap, subsequent regmap access is not going to
-+ * fail and we skip error checks from this point.
-+ */
-+ ret = regmap_read(priv->map, ASPEED_ESPI_CTRL, &ctrl);
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to read ctrl register\n");
-+ goto err_clk_disable_out;
-+ }
-+ regmap_write(priv->map, ASPEED_ESPI_CTRL,
-+ ctrl | ASPEED_ESPI_CTRL_OOB_CHRDY);
-+
-+ priv->pltrstn_miscdev.minor = MISC_DYNAMIC_MINOR;
-+ priv->pltrstn_miscdev.name = "espi-pltrstn";
-+ priv->pltrstn_miscdev.fops = &aspeed_espi_pltrstn_fops;
-+ priv->pltrstn_miscdev.parent = &pdev->dev;
-+
-+ ret = misc_register(&priv->pltrstn_miscdev);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Unable to register device\n");
-+ goto err_clk_disable_out;
-+ }
-+
-+ aspeed_espi_config_irq(priv);
-+ aspeed_espi_boot_ack(priv);
-+
-+ dev_info(&pdev->dev, "eSPI registered, irq %d\n", priv->irq);
-+
-+ return 0;
-+
-+err_clk_disable_out:
-+ clk_disable_unprepare(priv->clk);
-+
-+ return ret;
-+}
-+
-+static int aspeed_espi_remove(struct platform_device *pdev)
-+{
-+ struct aspeed_espi *priv = dev_get_drvdata(&pdev->dev);
-+
-+ misc_deregister(&priv->pltrstn_miscdev);
-+ clk_disable_unprepare(priv->clk);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id of_espi_match_table[] = {
-+ { .compatible = "aspeed,ast2500-espi-slave" },
-+ { .compatible = "aspeed,ast2600-espi-slave" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, of_espi_match_table);
-+
-+static struct platform_driver aspeed_espi_driver = {
-+ .driver = {
-+ .name = KBUILD_MODNAME,
-+ .of_match_table = of_match_ptr(of_espi_match_table),
-+ },
-+ .probe = aspeed_espi_probe,
-+ .remove = aspeed_espi_remove,
-+};
-+module_platform_driver(aspeed_espi_driver);
-+
-+MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>");
-+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>");
-+MODULE_DESCRIPTION("Aspeed eSPI driver");
-+MODULE_LICENSE("GPL v2");
-diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h
-index 3d90582a813f..1e18364de03d 100644
---- a/include/dt-bindings/clock/ast2600-clock.h
-+++ b/include/dt-bindings/clock/ast2600-clock.h
-@@ -104,6 +104,7 @@
- #define ASPEED_RESET_PECI 36
- #define ASPEED_RESET_MII 35
- #define ASPEED_RESET_I2C 34
-+#define ASPEED_RESET_ESPI 32
- #define ASPEED_RESET_H2X 31
- #define ASPEED_RESET_GP_MCU 30
- #define ASPEED_RESET_DP_MCU 29
---
-2.7.4
-