summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch403
1 files changed, 182 insertions, 221 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch
index d66e84beb..b4b1bcad8 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch
@@ -1,4 +1,4 @@
-From c111aac36e2f4fa1149662c85883407315ba76a6 Mon Sep 17 00:00:00 2001
+From 39f76bd49fd481999cf51fbdfbea3e820efc7227 Mon Sep 17 00:00:00 2001
From: Yong Li <yong.b.li@intel.com>
Date: Mon, 13 Nov 2017 16:29:44 +0800
Subject: [PATCH] Aspeed LPC SIO driver
@@ -13,9 +13,9 @@ Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
arch/arm/boot/dts/aspeed-g5.dtsi | 7 +
drivers/soc/aspeed/Kconfig | 7 +
drivers/soc/aspeed/Makefile | 1 +
- drivers/soc/aspeed/aspeed-lpc-sio.c | 450 +++++++++++++++++++++
- include/uapi/linux/aspeed-lpc-sio.h | 44 ++
- 7 files changed, 533 insertions(+)
+ drivers/soc/aspeed/aspeed-lpc-sio.c | 410 +++++++++++++++++++++
+ include/uapi/linux/aspeed-lpc-sio.h | 45 +++
+ 7 files changed, 494 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/aspeed/aspeed-lpc-sio.txt
create mode 100644 drivers/soc/aspeed/aspeed-lpc-sio.c
create mode 100644 include/uapi/linux/aspeed-lpc-sio.h
@@ -110,14 +110,15 @@ index f3ff29b874ed..2e547cc47e62 100644
obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.o
diff --git a/drivers/soc/aspeed/aspeed-lpc-sio.c b/drivers/soc/aspeed/aspeed-lpc-sio.c
new file mode 100644
-index 000000000000..c717a3182320
+index 000000000000..d4a4da112ff4
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-lpc-sio.c
-@@ -0,0 +1,450 @@
+@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2012-2017 ASPEED Technology Inc.
-+// Copyright (c) 2017-2019 Intel Corporation
++// Copyright (c) 2017-2020 Intel Corporation
+
++#include <linux/aspeed-lpc-sio.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/miscdevice.h>
@@ -128,62 +129,67 @@ index 000000000000..c717a3182320
+#include <linux/poll.h>
+#include <linux/regmap.h>
+
-+#include <linux/aspeed-lpc-sio.h>
-+
-+#define SOC_NAME "aspeed"
-+#define DEVICE_NAME "lpc-sio"
-+
-+#define AST_LPC_SWCR0300 0x0
-+#define LPC_PWRGD_STS (1 << 30)
-+#define LPC_PWRGD_RISING_EVT_STS (1 << 29)
-+#define LPC_PWRGD_FALLING_EVT_STS (1 << 28)
-+#define LPC_PWRBTN_STS (1 << 27)
-+#define LPC_PWRBTN_RISING_EVT_STS (1 << 26)
-+#define LPC_PWRBTN_FALLING_EVT_STS (1 << 25)
-+#define LPC_S5N_STS (1 << 21)
-+#define LPC_S5N_RISING_EVT_STS (1 << 20)
-+#define LPC_S5N_FALLING_EVT_STS (1 << 19)
-+#define LPC_S3N_STS (1 << 18)
-+#define LPC_S3N_RISING_EVT_STS (1 << 17)
-+#define LPC_S3N_FALLING_EVT_STS (1 << 16)
-+#define LPC_PWBTO_RAW_STS (1 << 15)
-+#define LPC_LAST_ONCTL_STS (1 << 14)
-+#define LPC_WAS_PFAIL_STS (1 << 13)
-+#define LPC_POWER_UP_FAIL_STS (1 << 12) /* Crowbar */
-+#define LPC_PWRBTN_OVERRIDE_STS (1 << 11)
-+
-+#define AST_LPC_SWCR0704 0x4
-+
-+#define AST_LPC_SWCR0B08 0x8
-+#define LPC_PWREQ_OUTPUT_LEVEL (1 << 25)
-+#define LPC_PWBTO_OUTPUT_LEVEL (1 << 24)
-+#define LPC_ONCTL_STS (1 << 15)
-+#define LPC_ONCTL_GPIO_LEVEL (1 << 14)
-+#define LPC_ONCTL_EN_GPIO_OUTPUT (1 << 13)
-+#define LPC_ONCTL_EN_GPIO_MODE (1 << 12)
-+
-+#define AST_LPC_SWCR0F0C 0xC
-+#define AST_LPC_SWCR1310 0x10
-+#define AST_LPC_SWCR1714 0x14
-+#define AST_LPC_SWCR1B18 0x18
-+#define AST_LPC_SWCR1F1C 0x1C
-+#define AST_LPC_ACPIE3E0 0x20
-+#define AST_LPC_ACPIC1C0 0x24
-+#define AST_LPC_ACPIB3B0 0x28
-+#define AST_LPC_ACPIB7B4 0x2C
++#define SOC_NAME "aspeed"
++#define DEVICE_NAME "lpc-sio"
++
++#define AST_LPC_SWCR0300 0x00
++#define LPC_PWRGD_STS BIT(30)
++#define LPC_PWRGD_RISING_EVT_STS BIT(29)
++#define LPC_PWRGD_FALLING_EVT_STS BIT(28)
++#define LPC_PWRBTN_STS BIT(27)
++#define LPC_PWRBTN_RISING_EVT_STS BIT(26)
++#define LPC_PWRBTN_FALLING_EVT_STS BIT(25)
++#define LPC_S5N_STS BIT(21)
++#define LPC_S5N_RISING_EVT_STS BIT(20)
++#define LPC_S5N_FALLING_EVT_STS BIT(19)
++#define LPC_S3N_STS BIT(18)
++#define LPC_S3N_RISING_EVT_STS BIT(17)
++#define LPC_S3N_FALLING_EVT_STS BIT(16)
++#define LPC_PWBTO_RAW_STS BIT(15)
++#define LPC_LAST_ONCTL_STS BIT(14)
++#define LPC_WAS_PFAIL_STS BIT(13)
++#define LPC_POWER_UP_FAIL_STS BIT(12) /* Crowbar */
++#define LPC_PWRBTN_OVERRIDE_STS BIT(11)
++#define LPC_BMC_TRIG_WAKEUP_EVT_STS BIT(8)
++
++#define AST_LPC_SWCR0704 0x04
++#define LPC_BMC_TRIG_WAKEUP_EVT_EN BIT(8)
++
++#define AST_LPC_SWCR0B08 0x08
++#define LPC_PWREQ_OUTPUT_LEVEL BIT(25)
++#define LPC_PWBTO_OUTPUT_LEVEL BIT(24)
++#define LPC_ONCTL_STS BIT(15)
++#define LPC_ONCTL_GPIO_LEVEL BIT(14)
++#define LPC_ONCTL_EN_GPIO_OUTPUT BIT(13)
++#define LPC_ONCTL_EN_GPIO_MODE BIT(12)
++#define LPC_BMC_TRIG_WAKEUP_EVT BIT(6)
++
++#define AST_LPC_SWCR0F0C 0x0C
++#define AST_LPC_SWCR1310 0x10
++#define AST_LPC_SWCR1714 0x14
++#define AST_LPC_SWCR1B18 0x18
++#define AST_LPC_SWCR1F1C 0x1C
++#define AST_LPC_ACPIE3E0 0x20
++#define AST_LPC_ACPIC1C0 0x24
++
++#define AST_LPC_ACPIB3B0 0x28
++#define LPC_BMC_TRIG_SCI_EVT_STS BIT(8)
++
++#define AST_LPC_ACPIB7B4 0x2C
++#define LPC_BMC_TRIG_SCI_EVT_EN BIT(8)
+
+struct aspeed_lpc_sio {
-+ struct miscdevice miscdev;
-+ struct regmap *regmap;
-+ struct clk *clk;
-+ struct semaphore lock;
-+ unsigned int reg_base;
++ struct miscdevice miscdev;
++ struct regmap *regmap;
++ struct clk *clk;
++ struct semaphore lock;
++ unsigned int reg_base;
+};
+
+static struct aspeed_lpc_sio *file_aspeed_lpc_sio(struct file *file)
+{
+ return container_of(file->private_data, struct aspeed_lpc_sio,
-+ miscdev);
++ miscdev);
+}
+
+static int aspeed_lpc_sio_open(struct inode *inode, struct file *filp)
@@ -196,7 +202,8 @@ index 000000000000..c717a3182320
+ LPC_S5N_FALLING_EVT_STS | \
+ LPC_S3N_RISING_EVT_STS | \
+ LPC_S3N_FALLING_EVT_STS)
-+/*************************************
++
++/*
+ * SLPS3n SLPS5n State
+ * ---------------------------------
+ * 1 1 S12
@@ -205,33 +212,20 @@ index 000000000000..c717a3182320
+ *************************************
+ */
+
-+static long sio_get_acpi_state(struct aspeed_lpc_sio *lpc_sio,
-+ struct sio_ioctl_data *sio_data)
++static void sio_get_acpi_state(struct aspeed_lpc_sio *lpc_sio,
++ struct sio_ioctl_data *sio_data)
+{
-+ u32 reg;
-+ u32 val;
-+ int rc;
++ u32 reg, val;
+
+ reg = lpc_sio->reg_base + AST_LPC_SWCR0300;
-+ rc = regmap_read(lpc_sio->regmap, reg, &val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_read(lpc_sio->regmap, reg, &val);
+
+ /* update the ACPI state event status */
+ if (sio_data->param != 0) {
+ if (val & LPC_SLP3N5N_EVENT_STATUS) {
+ sio_data->param = 1;
-+ rc = regmap_write(lpc_sio->regmap, reg,
-+ LPC_SLP3N5N_EVENT_STATUS);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_write() failed with %d(reg:0x%x)\n",
-+ rc, reg);
-+ return rc;
-+ }
++ regmap_write(lpc_sio->regmap, reg,
++ LPC_SLP3N5N_EVENT_STATUS);
+ } else {
+ sio_data->param = 0;
+ }
@@ -243,85 +237,52 @@ index 000000000000..c717a3182320
+ sio_data->data = ACPI_STATE_S3I;
+ else
+ sio_data->data = ACPI_STATE_S45;
-+
-+ return 0;
+}
+
+#define LPC_PWRGD_EVENT_STATUS ( \
+ LPC_PWRGD_RISING_EVT_STS | \
+ LPC_PWRGD_FALLING_EVT_STS)
+
-+static long sio_get_pwrgd_status(struct aspeed_lpc_sio *lpc_sio,
-+ struct sio_ioctl_data *sio_data)
++static void sio_get_pwrgd_status(struct aspeed_lpc_sio *lpc_sio,
++ struct sio_ioctl_data *sio_data)
+{
-+ u32 reg;
-+ u32 val;
-+ int rc;
++ u32 reg, val;
+
+ reg = lpc_sio->reg_base + AST_LPC_SWCR0300;
-+ rc = regmap_read(lpc_sio->regmap, reg, &val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_read(lpc_sio->regmap, reg, &val);
+
+ /* update the PWRGD event status */
+ if (sio_data->param != 0) {
+ if (val & LPC_PWRGD_EVENT_STATUS) {
+ sio_data->param = 1;
-+ rc = regmap_write(lpc_sio->regmap, reg,
-+ LPC_PWRGD_EVENT_STATUS);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_write() failed with %d(reg:0x%x)\n",
-+ rc, reg);
-+ return rc;
-+ }
++ regmap_write(lpc_sio->regmap, reg,
++ LPC_PWRGD_EVENT_STATUS);
+ } else {
+ sio_data->param = 0;
+ }
+ }
+
+ sio_data->data = (val & LPC_PWRGD_STS) != 0 ? 1 : 0;
-+
-+ return 0;
+}
+
-+static long sio_get_onctl_status(struct aspeed_lpc_sio *lpc_sio,
-+ struct sio_ioctl_data *sio_data)
++static void sio_get_onctl_status(struct aspeed_lpc_sio *lpc_sio,
++ struct sio_ioctl_data *sio_data)
+{
-+ u32 reg;
-+ u32 val;
-+ int rc;
++ u32 reg, val;
+
+ reg = lpc_sio->reg_base + AST_LPC_SWCR0B08;
-+ rc = regmap_read(lpc_sio->regmap, reg, &val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_read(lpc_sio->regmap, reg, &val);
+
+ sio_data->data = (val & LPC_ONCTL_STS) != 0 ? 1 : 0;
-+
-+ return 0;
+}
+
-+static long sio_set_onctl_gpio(struct aspeed_lpc_sio *lpc_sio,
-+ struct sio_ioctl_data *sio_data)
++static void sio_set_onctl_gpio(struct aspeed_lpc_sio *lpc_sio,
++ struct sio_ioctl_data *sio_data)
+{
-+ u32 reg;
-+ u32 val;
-+ int rc;
++ u32 reg, val;
+
+ reg = lpc_sio->reg_base + AST_LPC_SWCR0B08;
-+ rc = regmap_read(lpc_sio->regmap, reg, &val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_read(lpc_sio->regmap, reg, &val);
+
+ /* Enable ONCTL GPIO mode */
+ if (sio_data->param != 0) {
@@ -333,112 +294,103 @@ index 000000000000..c717a3182320
+ else
+ val &= ~LPC_ONCTL_GPIO_LEVEL;
+
-+ rc = regmap_write(lpc_sio->regmap, reg, val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_write() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_write(lpc_sio->regmap, reg, val);
+ } else {
+ val &= ~LPC_ONCTL_EN_GPIO_MODE;
-+ rc = regmap_write(lpc_sio->regmap, reg, val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_write() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_write(lpc_sio->regmap, reg, val);
+ }
-+
-+ return 0;
+}
+
-+static long sio_get_pwrbtn_override(struct aspeed_lpc_sio *lpc_sio,
-+ struct sio_ioctl_data *sio_data)
++static void sio_get_pwrbtn_override(struct aspeed_lpc_sio *lpc_sio,
++ struct sio_ioctl_data *sio_data)
+{
-+ u32 reg;
-+ u32 val;
-+ int rc;
++ u32 reg, val;
+
+ reg = lpc_sio->reg_base + AST_LPC_SWCR0300;
-+ rc = regmap_read(lpc_sio->regmap, reg, &val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_read(lpc_sio->regmap, reg, &val);
+
+ /* clear the PWRBTN OVERRIDE status */
-+ if (sio_data->param != 0) {
-+ if (val & LPC_PWRBTN_OVERRIDE_STS) {
-+ rc = regmap_write(lpc_sio->regmap, reg,
-+ LPC_PWRBTN_OVERRIDE_STS);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_write() failed with %d(reg:0x%x)\n",
-+ rc, reg);
-+ return rc;
-+ }
-+ }
-+ }
++ if (sio_data->param != 0 && val & LPC_PWRBTN_OVERRIDE_STS)
++ regmap_write(lpc_sio->regmap, reg, LPC_PWRBTN_OVERRIDE_STS);
+
+ sio_data->data = (val & LPC_PWRBTN_OVERRIDE_STS) != 0 ? 1 : 0;
-+
-+ return 0;
+}
+
-+static long sio_get_pfail_status(struct aspeed_lpc_sio *lpc_sio,
-+ struct sio_ioctl_data *sio_data)
++static void sio_get_pfail_status(struct aspeed_lpc_sio *lpc_sio,
++ struct sio_ioctl_data *sio_data)
+{
-+ u32 reg;
-+ u32 val;
-+ int rc;
++ u32 reg, val;
+
+ reg = lpc_sio->reg_base + AST_LPC_SWCR0300;
-+ rc = regmap_read(lpc_sio->regmap, reg, &val);
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_read(lpc_sio->regmap, reg, &val);
+
+ /* [ASPEED]: SWCR_03_00[13] (Was_pfail: default 1) is used to identify
+ * this current booting is from AC loss (not DC loss) if FW cleans this
+ * bit after booting successfully every time.
+ **********************************************************************/
+ if (val & LPC_WAS_PFAIL_STS) {
-+ rc = regmap_write(lpc_sio->regmap, reg, 0); /* W0C */
-+ if (rc) {
-+ dev_err(lpc_sio->miscdev.parent,
-+ "regmap_write() failed with %d(reg:0x%x)\n", rc, reg);
-+ return rc;
-+ }
++ regmap_write(lpc_sio->regmap, reg, 0); /* W0C */
+ sio_data->data = 1;
+ } else {
+ sio_data->data = 0;
+ }
++}
+
-+ return 0;
++static void sio_set_bmc_sci_event(struct aspeed_lpc_sio *lpc_sio,
++ struct sio_ioctl_data *sio_data)
++{
++ u32 reg;
++
++ if (sio_data->param) {
++ reg = lpc_sio->reg_base + AST_LPC_ACPIB7B4;
++ regmap_write_bits(lpc_sio->regmap, reg,
++ LPC_BMC_TRIG_SCI_EVT_EN,
++ LPC_BMC_TRIG_SCI_EVT_EN);
++
++ reg = lpc_sio->reg_base + AST_LPC_SWCR0704;
++ regmap_write_bits(lpc_sio->regmap, reg,
++ LPC_BMC_TRIG_WAKEUP_EVT_EN,
++ LPC_BMC_TRIG_WAKEUP_EVT_EN);
++
++ reg = lpc_sio->reg_base + AST_LPC_SWCR0B08;
++ regmap_write_bits(lpc_sio->regmap, reg,
++ LPC_BMC_TRIG_WAKEUP_EVT,
++ LPC_BMC_TRIG_WAKEUP_EVT);
++ } else {
++ reg = lpc_sio->reg_base + AST_LPC_SWCR0300;
++ regmap_write_bits(lpc_sio->regmap, reg,
++ LPC_BMC_TRIG_WAKEUP_EVT_STS,
++ LPC_BMC_TRIG_WAKEUP_EVT_STS);
++
++ reg = lpc_sio->reg_base + AST_LPC_ACPIB3B0;
++ regmap_write_bits(lpc_sio->regmap, reg,
++ LPC_BMC_TRIG_SCI_EVT_STS,
++ LPC_BMC_TRIG_SCI_EVT_STS);
++ }
++
++ sio_data->data = sio_data->param;
+}
+
-+typedef long (*sio_cmd_fn) (struct aspeed_lpc_sio *sio_dev,
-+ struct sio_ioctl_data *sio_data);
++typedef void (*sio_cmd_fn) (struct aspeed_lpc_sio *sio_dev,
++ struct sio_ioctl_data *sio_data);
++
+static sio_cmd_fn sio_cmd_handle[SIO_MAX_CMD] = {
-+ [SIO_GET_ACPI_STATE] = sio_get_acpi_state,
-+ [SIO_GET_PWRGD_STATUS] = sio_get_pwrgd_status,
-+ [SIO_GET_ONCTL_STATUS] = sio_get_onctl_status,
-+ [SIO_SET_ONCTL_GPIO] = sio_set_onctl_gpio,
-+ [SIO_GET_PWRBTN_OVERRIDE] = sio_get_pwrbtn_override,
-+ [SIO_GET_PFAIL_STATUS] = sio_get_pfail_status,
++ [SIO_GET_ACPI_STATE] = sio_get_acpi_state,
++ [SIO_GET_PWRGD_STATUS] = sio_get_pwrgd_status,
++ [SIO_GET_ONCTL_STATUS] = sio_get_onctl_status,
++ [SIO_SET_ONCTL_GPIO] = sio_set_onctl_gpio,
++ [SIO_GET_PWRBTN_OVERRIDE] = sio_get_pwrbtn_override,
++ [SIO_GET_PFAIL_STATUS] = sio_get_pfail_status,
++ [SIO_SET_BMC_SCI_EVENT] = sio_set_bmc_sci_event,
+};
+
+static long aspeed_lpc_sio_ioctl(struct file *file, unsigned int cmd,
-+ unsigned long param)
++ unsigned long param)
+{
+ struct aspeed_lpc_sio *lpc_sio = file_aspeed_lpc_sio(file);
-+ long ret;
-+ sio_cmd_fn cmd_fn;
+ struct sio_ioctl_data sio_data;
-+
++ sio_cmd_fn cmd_fn;
++ long ret;
+
+ if (copy_from_user(&sio_data, (void __user *)param, sizeof(sio_data)))
+ return -EFAULT;
@@ -447,18 +399,14 @@ index 000000000000..c717a3182320
+ return -EINVAL;
+
+ cmd_fn = sio_cmd_handle[sio_data.sio_cmd];
-+ if (cmd_fn == NULL)
++ if (!cmd_fn)
+ return -EINVAL;
+
+ if (down_interruptible(&lpc_sio->lock) != 0)
+ return -ERESTARTSYS;
+
-+ ret = cmd_fn(lpc_sio, &sio_data);
-+ if (ret == 0) {
-+ if (copy_to_user((void __user *)param, &sio_data,
-+ sizeof(sio_data)))
-+ ret = -EFAULT;
-+ }
++ cmd_fn(lpc_sio, &sio_data);
++ ret = copy_to_user((void __user *)param, &sio_data, sizeof(sio_data));
+
+ up(&lpc_sio->lock);
+
@@ -475,7 +423,8 @@ index 000000000000..c717a3182320
+{
+ struct aspeed_lpc_sio *lpc_sio;
+ struct device *dev;
-+ int rc;
++ u32 val;
++ int ret;
+
+ dev = &pdev->dev;
+
@@ -485,40 +434,51 @@ index 000000000000..c717a3182320
+
+ dev_set_drvdata(&pdev->dev, lpc_sio);
+
-+ rc = of_property_read_u32(dev->of_node, "reg", &lpc_sio->reg_base);
-+ if (rc) {
++ ret = of_property_read_u32(dev->of_node, "reg", &lpc_sio->reg_base);
++ if (ret) {
+ dev_err(dev, "Couldn't read reg device-tree property\n");
-+ return rc;
++ return ret;
+ }
+
-+ lpc_sio->regmap = syscon_node_to_regmap(
-+ pdev->dev.parent->of_node);
++ lpc_sio->regmap = syscon_node_to_regmap(pdev->dev.parent->of_node);
+ if (IS_ERR(lpc_sio->regmap)) {
+ dev_err(dev, "Couldn't get regmap\n");
+ return -ENODEV;
+ }
+
++ /*
++ * 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(lpc_sio->regmap, AST_LPC_SWCR0300, &val);
++ if (ret) {
++ dev_err(dev, "failed to read regmap\n");
++ return ret;
++ }
++
+ sema_init(&lpc_sio->lock, 1);
+
+ lpc_sio->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(lpc_sio->clk)) {
-+ rc = PTR_ERR(lpc_sio->clk);
-+ if (rc != -EPROBE_DEFER)
++ ret = PTR_ERR(lpc_sio->clk);
++ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "couldn't get clock\n");
-+ return rc;
++ return ret;
+ }
-+ rc = clk_prepare_enable(lpc_sio->clk);
-+ if (rc) {
++ ret = clk_prepare_enable(lpc_sio->clk);
++ if (ret) {
+ dev_err(dev, "couldn't enable clock\n");
-+ return rc;
++ return ret;
+ }
+
+ lpc_sio->miscdev.minor = MISC_DYNAMIC_MINOR;
+ lpc_sio->miscdev.name = DEVICE_NAME;
+ lpc_sio->miscdev.fops = &aspeed_lpc_sio_fops;
+ lpc_sio->miscdev.parent = dev;
-+ rc = misc_register(&lpc_sio->miscdev);
-+ if (rc) {
++ ret = misc_register(&lpc_sio->miscdev);
++ if (ret) {
+ dev_err(dev, "Unable to register device\n");
+ goto err;
+ }
@@ -531,7 +491,7 @@ index 000000000000..c717a3182320
+err:
+ clk_disable_unprepare(lpc_sio->clk);
+
-+ return rc;
++ return ret;
+}
+
+static int aspeed_lpc_sio_remove(struct platform_device *pdev)
@@ -551,25 +511,25 @@ index 000000000000..c717a3182320
+MODULE_DEVICE_TABLE(of, aspeed_lpc_sio_match);
+
+static struct platform_driver aspeed_lpc_sio_driver = {
-+ .driver = {
++ .driver = {
+ .name = SOC_NAME "-" DEVICE_NAME,
-+ .of_match_table = aspeed_lpc_sio_match,
++ .of_match_table = of_match_ptr(aspeed_lpc_sio_match),
+ },
-+ .probe = aspeed_lpc_sio_probe,
-+ .remove = aspeed_lpc_sio_remove,
++ .probe = aspeed_lpc_sio_probe,
++ .remove = aspeed_lpc_sio_remove,
+};
+module_platform_driver(aspeed_lpc_sio_driver);
+
-+MODULE_LICENSE("GPL");
++MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_AUTHOR("Yong Li <yong.blli@linux.intel.com>");
+MODULE_DESCRIPTION("ASPEED AST LPC SIO device driver");
diff --git a/include/uapi/linux/aspeed-lpc-sio.h b/include/uapi/linux/aspeed-lpc-sio.h
new file mode 100644
-index 000000000000..5dc1efd4a426
+index 000000000000..acf89a7d2b4a
--- /dev/null
+++ b/include/uapi/linux/aspeed-lpc-sio.h
-@@ -0,0 +1,44 @@
+@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012-2020 ASPEED Technology Inc.
+ * Copyright (c) 2017 Intel Corporation
@@ -600,6 +560,7 @@ index 000000000000..5dc1efd4a426
+ SIO_SET_ONCTL_GPIO,
+ SIO_GET_PWRBTN_OVERRIDE,
+ SIO_GET_PFAIL_STATUS, /* Start from AC Loss */
++ SIO_SET_BMC_SCI_EVENT,
+
+ SIO_MAX_CMD
+};