summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0046-misc-Add-clock-control-logic-into-Aspeed-LPC-MBOX-dr.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0046-misc-Add-clock-control-logic-into-Aspeed-LPC-MBOX-dr.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0046-misc-Add-clock-control-logic-into-Aspeed-LPC-MBOX-dr.patch166
1 files changed, 166 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0046-misc-Add-clock-control-logic-into-Aspeed-LPC-MBOX-dr.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0046-misc-Add-clock-control-logic-into-Aspeed-LPC-MBOX-dr.patch
new file mode 100644
index 000000000..220283e24
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0046-misc-Add-clock-control-logic-into-Aspeed-LPC-MBOX-dr.patch
@@ -0,0 +1,166 @@
+From db310b43e5b444a4e2854f3d69d002c2f0d0605c Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Wed, 13 Mar 2019 15:53:24 -0700
+Subject: [PATCH] misc: Add clock control logic into Aspeed LPC MBOX driver
+
+If LPC MBOX driver is registered ahead of lpc-ctrl module, LPC
+MBOX block will be enabled without heart beating of LCLK until
+lpc-ctrl enables the LCLK. This issue causes improper handling on
+host interrupts when the host sends interrupt in that time frame.
+Then kernel eventually forcibly disables the interrupt with dumping
+stack and printing a 'nobody cared this irq' message out.
+
+To prevent this issue, all LPC sub-nodes should enable LCLK
+individually so this patch adds clock control logic into the LPC
+MBOX driver.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ arch/arm/boot/dts/aspeed-g4.dtsi | 1 +
+ arch/arm/boot/dts/aspeed-g5.dtsi | 1 +
+ drivers/misc/aspeed-lpc-mbox.c | 42 +++++++++++++++++++++++++++++++---------
+ 3 files changed, 35 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
+index a5072ed1f823..729245b74c13 100644
+--- a/arch/arm/boot/dts/aspeed-g4.dtsi
++++ b/arch/arm/boot/dts/aspeed-g4.dtsi
+@@ -389,6 +389,7 @@
+ reg = <0x180 0x5c>;
+ interrupts = <46>;
+ #mbox-cells = <1>;
++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
+index 6a2f161e7548..df9d63a94264 100644
+--- a/arch/arm/boot/dts/aspeed-g5.dtsi
++++ b/arch/arm/boot/dts/aspeed-g5.dtsi
+@@ -493,6 +493,7 @@
+ reg = <0x180 0x5c>;
+ interrupts = <46>;
+ #mbox-cells = <1>;
++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
+ status = "disabled";
+ };
+ };
+diff --git a/drivers/misc/aspeed-lpc-mbox.c b/drivers/misc/aspeed-lpc-mbox.c
+index 0933e0553953..f105d27786ac 100644
+--- a/drivers/misc/aspeed-lpc-mbox.c
++++ b/drivers/misc/aspeed-lpc-mbox.c
+@@ -7,6 +7,7 @@
+ * 2 of the License, or (at your option) any later version.
+ */
+
++#include <linux/clk.h>
+ #include <linux/interrupt.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/miscdevice.h>
+@@ -37,7 +38,9 @@
+ struct aspeed_mbox {
+ struct miscdevice miscdev;
+ struct regmap *regmap;
++ struct clk *clk;
+ unsigned int base;
++ int irq;
+ wait_queue_head_t queue;
+ struct mutex mutex;
+ };
+@@ -237,16 +240,16 @@ static int aspeed_mbox_config_irq(struct aspeed_mbox *mbox,
+ struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+- int rc, irq;
++ int rc;
+
+- irq = irq_of_parse_and_map(dev->of_node, 0);
+- if (!irq)
++ mbox->irq = platform_get_irq(pdev, 0);
++ if (!mbox->irq)
+ return -ENODEV;
+
+- rc = devm_request_irq(dev, irq, aspeed_mbox_irq,
+- IRQF_SHARED, DEVICE_NAME, mbox);
++ rc = devm_request_irq(dev, mbox->irq, aspeed_mbox_irq,
++ IRQF_SHARED, DEVICE_NAME, mbox);
+ if (rc < 0) {
+- dev_err(dev, "Unable to request IRQ %d\n", irq);
++ dev_err(dev, "Unable to request IRQ %d\n", mbox->irq);
+ return rc;
+ }
+
+@@ -301,6 +304,19 @@ static int aspeed_mbox_probe(struct platform_device *pdev)
+ mutex_init(&mbox->mutex);
+ init_waitqueue_head(&mbox->queue);
+
++ mbox->clk = devm_clk_get(dev, NULL);
++ if (IS_ERR(mbox->clk)) {
++ rc = PTR_ERR(mbox->clk);
++ if (rc != -EPROBE_DEFER)
++ dev_err(dev, "couldn't get clock\n");
++ return rc;
++ }
++ rc = clk_prepare_enable(mbox->clk);
++ if (rc) {
++ dev_err(dev, "couldn't enable clock\n");
++ return rc;
++ }
++
+ mbox->miscdev.minor = MISC_DYNAMIC_MINOR;
+ mbox->miscdev.name = DEVICE_NAME;
+ mbox->miscdev.fops = &aspeed_mbox_fops;
+@@ -308,17 +324,24 @@ static int aspeed_mbox_probe(struct platform_device *pdev)
+ rc = misc_register(&mbox->miscdev);
+ if (rc) {
+ dev_err(dev, "Unable to register device\n");
+- return rc;
++ goto err;
+ }
+
+ rc = aspeed_mbox_config_irq(mbox, pdev);
+ if (rc) {
+ dev_err(dev, "Failed to configure IRQ\n");
+ misc_deregister(&mbox->miscdev);
+- return rc;
++ goto err;
+ }
+
++ dev_info(&pdev->dev, "LPC mbox registered, irq %d\n", mbox->irq);
++
+ return 0;
++
++err:
++ clk_disable_unprepare(mbox->clk);
++
++ return rc;
+ }
+
+ static int aspeed_mbox_remove(struct platform_device *pdev)
+@@ -326,6 +349,7 @@ static int aspeed_mbox_remove(struct platform_device *pdev)
+ struct aspeed_mbox *mbox = dev_get_drvdata(&pdev->dev);
+
+ misc_deregister(&mbox->miscdev);
++ clk_disable_unprepare(mbox->clk);
+
+ return 0;
+ }
+@@ -335,6 +359,7 @@ static const struct of_device_id aspeed_mbox_match[] = {
+ { .compatible = "aspeed,ast2500-mbox" },
+ { },
+ };
++MODULE_DEVICE_TABLE(of, aspeed_mbox_match);
+
+ static struct platform_driver aspeed_mbox_driver = {
+ .driver = {
+@@ -347,7 +372,6 @@ static struct platform_driver aspeed_mbox_driver = {
+
+ module_platform_driver(aspeed_mbox_driver);
+
+-MODULE_DEVICE_TABLE(of, aspeed_mbox_match);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Cyril Bur <cyrilbur@gmail.com>");
+ MODULE_DESCRIPTION("Aspeed mailbox device driver");
+--
+2.7.4
+