Merge pull request #4991 from jernejsk/crust-updt

Allwinner: Improve suspend/resume
This commit is contained in:
CvH 2021-01-19 19:02:44 +01:00 committed by GitHub
commit e417de73bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 2714 additions and 1345 deletions

View File

@ -2,8 +2,8 @@
# Copyright (C) 2020-present Team LibreELEC (https://libreelec.tv)
PKG_NAME="crust"
PKG_VERSION="1609cb0dbb70e5698032a0e39408756467289e6e"
PKG_SHA256="f02df0e6e50f2fb1029103f452d4e5e27f54cb1635c6ab3fca3d2ac24747844c"
PKG_VERSION="2abb49c37b0302399b98498b9a51f5ed30454aea"
PKG_SHA256="62da63ce5f35c41b7b9cbc9ec8c89dbd52e41a60bde00218ac747a1b335803cb"
PKG_ARCH="arm aarch64"
PKG_LICENSE="BSD-3c"
PKG_SITE="https://github.com/crust-firmware/crust"
@ -38,6 +38,7 @@ make_target() {
fi
# Boards with a PMIC need to disable CONFIG_PMIC_SHUTDOWN to get CIR wakeup from suspend
echo "CONFIG_PMIC_SHUTDOWN=n" >> configs/$CRUST_CONFIG
echo "CONFIG_CIR=y" >> configs/$CRUST_CONFIG
make $CRUST_CONFIG
make scp
}

View File

@ -1,7 +1,7 @@
From da5268aa6c9a552ceebf74263acf997489368adc Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Sat, 16 Jan 2021 10:58:14 +0100
Subject: [PATCH 01/14] HACK: h6: Add HDMI sound card
Subject: [PATCH] HACK: h6: Add HDMI sound card
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
@ -35,7 +35,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
soc {
compatible = "simple-bus";
#address-cells = <1>;
@@ -651,7 +669,6 @@
@@ -652,7 +670,6 @@
dmas = <&dma 4>, <&dma 4>;
resets = <&ccu RST_BUS_I2S1>;
dma-names = "rx", "tx";
@ -43,7 +43,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
};
spdif: spdif@5093000 {
@@ -784,6 +801,7 @@
@@ -785,6 +802,7 @@
};
hdmi: hdmi@6000000 {

View File

@ -1,8 +1,7 @@
From 7f12904df66e28c2a5fa8ea652ed9eee48a22131 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Wed, 27 Mar 2019 13:21:06 +0100
Subject: [PATCH 02/14] net: stmmac: sun8i: Use devm_regulator_get for PHY
regulator
Subject: [PATCH] net: stmmac: sun8i: Use devm_regulator_get for PHY regulator
Use devm_regulator_get instead of devm_regulator_get_optional and rely
on dummy supply. This avoids NULL checks before regulator_enable/disable
@ -23,7 +22,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -544,12 +544,10 @@ static int sun8i_dwmac_init(struct platf
@@ -549,12 +549,10 @@ static int sun8i_dwmac_init(struct platf
struct sunxi_priv_data *gmac = priv;
int ret;
@ -40,7 +39,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
}
ret = clk_prepare_enable(gmac->tx_clk);
@@ -1017,8 +1015,7 @@ static void sun8i_dwmac_exit(struct plat
@@ -1021,8 +1019,7 @@ static void sun8i_dwmac_exit(struct plat
clk_disable_unprepare(gmac->tx_clk);
@ -50,7 +49,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1155,12 +1152,12 @@ static int sun8i_dwmac_probe(struct plat
@@ -1150,12 +1147,12 @@ static int sun8i_dwmac_probe(struct plat
}
/* Optional regulator for PHY */

View File

@ -1,7 +1,7 @@
From 455e29ad5f37b40532b9cf56781dab3c3eb275b5 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 20 Aug 2019 14:29:29 +0200
Subject: [PATCH 03/14] net: stmmac: sun8i: Rename PHY regulator variable to
Subject: [PATCH] net: stmmac: sun8i: Rename PHY regulator variable to
regulator_phy
We'll be adding further optional regulators, and this makes it clearer
@ -9,12 +9,12 @@ what the regulator is for.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 32 ++++++++++---------
1 file changed, 17 insertions(+), 15 deletions(-)
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 39 +++++++++----------
1 file changed, 19 insertions(+), 20 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -57,19 +57,21 @@ struct emac_variant {
@@ -57,20 +57,22 @@ struct emac_variant {
};
/* struct sunxi_priv_data - hold all sunxi private data
@ -25,6 +25,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
- * @variant: reference to the current board variant
- * @regmap: regmap for using the syscon
- * @internal_phy_powered: Does the internal PHY is enabled
- * @use_internal_phy: Is the internal PHY selected for use
- * @mux_handle: Internal pointer used by mdio-mux lib
+ * @tx_clk: reference to MAC TX clock
+ * @ephy_clk: reference to the optional EPHY clock for
@ -35,6 +36,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
+ * @variant: reference to the current board variant
+ * @regmap: regmap for using the syscon
+ * @internal_phy_powered: Does the internal PHY is enabled
+ * @use_internal_phy: Is the internal PHY selected for use
+ * @mux_handle: Internal pointer used by mdio-mux lib
*/
struct sunxi_priv_data {
@ -45,7 +47,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
struct reset_control *rst_ephy;
const struct emac_variant *variant;
struct regmap_field *regmap_field;
@@ -544,9 +546,9 @@ static int sun8i_dwmac_init(struct platf
@@ -549,9 +551,9 @@ static int sun8i_dwmac_init(struct platf
struct sunxi_priv_data *gmac = priv;
int ret;
@ -57,7 +59,17 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
return ret;
}
@@ -1015,7 +1017,7 @@ static void sun8i_dwmac_exit(struct plat
@@ -572,8 +574,7 @@ static int sun8i_dwmac_init(struct platf
err_disable_clk:
clk_disable_unprepare(gmac->tx_clk);
err_disable_regulator:
- if (gmac->regulator)
- regulator_disable(gmac->regulator);
+ regulator_disable(gmac->regulator_phy);
return ret;
}
@@ -1019,7 +1020,7 @@ static void sun8i_dwmac_exit(struct plat
clk_disable_unprepare(gmac->tx_clk);
@ -66,16 +78,18 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1152,9 +1154,9 @@ static int sun8i_dwmac_probe(struct plat
@@ -1147,11 +1148,9 @@ static int sun8i_dwmac_probe(struct plat
}
/* Optional regulator for PHY */
- gmac->regulator = devm_regulator_get(dev, "phy");
- if (IS_ERR(gmac->regulator)) {
- ret = PTR_ERR(gmac->regulator);
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "Failed to get PHY regulator (%d)\n", ret);
+ gmac->regulator_phy = devm_regulator_get(dev, "phy");
+ if (IS_ERR(gmac->regulator_phy)) {
+ ret = PTR_ERR(gmac->regulator_phy);
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get PHY regulator (%d)\n", ret);
+ dev_err_probe(dev, ret, "Failed to get PHY regulator\n");
return ret;
}

View File

@ -1,8 +1,8 @@
From a2903d15de86fc3ab455a665e22ad6e5c27f8c43 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 20 Aug 2019 14:31:38 +0200
Subject: [PATCH 04/14] net: stmmac: sun8i: Add support for enabling a
regulator for PHY I/O pins
Subject: [PATCH] net: stmmac: sun8i: Add support for enabling a regulator for
PHY I/O pins
Orange Pi 3 has two regulators that power the Realtek RTL8211E. According
to the phy datasheet, both regulators need to be enabled at the same time.
@ -12,8 +12,8 @@ driver.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 30 ++++++++++++++++---
1 file changed, 26 insertions(+), 4 deletions(-)
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@ -26,7 +26,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
* @rst_ephy: reference to the optional EPHY reset for
* the internal PHY
* @variant: reference to the current board variant
@@ -72,6 +74,7 @@ struct sunxi_priv_data {
@@ -73,6 +75,7 @@ struct sunxi_priv_data {
struct clk *tx_clk;
struct clk *ephy_clk;
struct regulator *regulator_phy;
@ -34,7 +34,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
struct reset_control *rst_ephy;
const struct emac_variant *variant;
struct regmap_field *regmap_field;
@@ -546,21 +549,30 @@ static int sun8i_dwmac_init(struct platf
@@ -551,10 +554,16 @@ static int sun8i_dwmac_init(struct platf
struct sunxi_priv_data *gmac = priv;
int ret;
@ -52,24 +52,16 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
}
ret = clk_prepare_enable(gmac->tx_clk);
if (ret) {
- if (gmac->regulator)
- regulator_disable(gmac->regulator);
dev_err(&pdev->dev, "Could not enable AHB clock\n");
- return ret;
+ goto err_disable_regulator_phy;
}
return 0;
+err_disable_regulator_phy:
+ regulator_disable(gmac->regulator_phy);
@@ -575,6 +584,8 @@ err_disable_clk:
clk_disable_unprepare(gmac->tx_clk);
err_disable_regulator:
regulator_disable(gmac->regulator_phy);
+err_disable_regulator_phy_io:
+ regulator_disable(gmac->regulator_phy_io);
+ return ret;
}
static void sun8i_dwmac_core_init(struct mac_device_info *hw,
@@ -1018,6 +1030,7 @@ static void sun8i_dwmac_exit(struct plat
return ret;
}
@@ -1021,6 +1032,7 @@ static void sun8i_dwmac_exit(struct plat
clk_disable_unprepare(gmac->tx_clk);
regulator_disable(gmac->regulator_phy);
@ -77,7 +69,7 @@ Signed-off-by: Ondrej Jirman <megous@megous.com>
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1162,6 +1175,15 @@ static int sun8i_dwmac_probe(struct plat
@@ -1154,6 +1166,15 @@ static int sun8i_dwmac_probe(struct plat
return ret;
}

View File

@ -1,7 +1,7 @@
From 3a078af461185f3ed34c182616365da3a60c6b77 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 20 Aug 2019 14:54:48 +0200
Subject: [PATCH 05/14] arm64: dts: allwinner: orange-pi-3: Enable ethernet
Subject: [PATCH] arm64: dts: allwinner: orange-pi-3: Enable ethernet
Orange Pi 3 has two regulators that power the Realtek RTL8211E
PHY. According to the datasheet, both regulators need to be enabled

View File

@ -1,7 +1,7 @@
From df7cfa735a251371d3bbee07994fc5e8af55e508 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Mon, 25 Dec 2017 12:10:59 +0800
Subject: [PATCH 07/14] arm64: allwinner: dts: h6: enable USB3 port on Pine H64
Subject: [PATCH] arm64: allwinner: dts: h6: enable USB3 port on Pine H64
Pine H64 board have a USB3 port, which is connected to the USB3 pins of
the H6 SoC, and the 5V power supply is controlled via GPIO (shared with

View File

@ -1,67 +0,0 @@
From e58355ab59c95b3ce708d3fdb417e3893170cfde Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 20 Aug 2019 14:34:57 +0200
Subject: [PATCH 06/14] net: stmmac: sun8i: Fix reboot issue with ethernet on
Orange Pi 3
We disable both phy regulators before reboot, so that they are in a
known state on the next boot. This should be done in u-boot, but
it doesn't support AXP806 yet, thus this workaround.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -17,6 +17,7 @@
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/stmmac.h>
@@ -80,6 +81,7 @@ struct sunxi_priv_data {
struct regmap_field *regmap_field;
bool internal_phy_powered;
void *mux_handle;
+ struct notifier_block reboot_nb;
};
/* EMAC clock register @ 0x30 in the "system control" address range */
@@ -1130,6 +1132,19 @@ out_put_node:
return regmap;
}
+
+static int sun8i_dwmac_reboot_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct sunxi_priv_data *gmac = container_of(nb, struct sunxi_priv_data,
+ reboot_nb);
+
+ regulator_disable(gmac->regulator_phy);
+ regulator_disable(gmac->regulator_phy_io);
+
+ return NOTIFY_DONE;
+}
+
static int sun8i_dwmac_probe(struct platform_device *pdev)
{
struct plat_stmmacenet_data *plat_dat;
@@ -1184,6 +1199,13 @@ static int sun8i_dwmac_probe(struct plat
return ret;
}
+ gmac->reboot_nb.notifier_call = sun8i_dwmac_reboot_notifier;
+ ret = devm_register_reboot_notifier(dev, &gmac->reboot_nb);
+ if (ret) {
+ dev_err(dev, "Failed to register reboot notifier (%d)\n", ret);
+ return ret;
+ }
+
/* The "GMAC clock control" register might be located in the
* CCU address range (on the R40), or the system control address
* range (on most other sun8i and later SoCs).

View File

@ -1,7 +1,7 @@
From 8d6daa429e4b4c97131b16a69cd34ab486b2c248 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Fri, 16 Aug 2019 16:40:20 +0200
Subject: [PATCH 08/14] arm64: dts: allwinner: h6: Add AC200 EPHY related nodes
Subject: [PATCH] arm64: dts: allwinner: h6: Add AC200 EPHY related nodes
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
@ -38,7 +38,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
};
watchdog: watchdog@30090a0 {
@@ -363,6 +377,13 @@
@@ -364,6 +378,13 @@
drive-strength = <40>;
};
@ -52,7 +52,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
hdmi_pins: hdmi-pins {
pins = "PH8", "PH9", "PH10";
function = "hdmi";
@@ -383,6 +404,11 @@
@@ -384,6 +405,11 @@
function = "i2c2";
};
@ -64,7 +64,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
mmc0_pins: mmc0-pins {
pins = "PF0", "PF1", "PF2", "PF3",
"PF4", "PF5";
@@ -409,6 +435,11 @@
@@ -410,6 +436,11 @@
bias-pull-up;
};
@ -76,7 +76,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
/omit-if-no-ref/
spi0_pins: spi0-pins {
pins = "PC0", "PC2", "PC3";
@@ -639,6 +670,31 @@
@@ -640,6 +671,31 @@
#size-cells = <0>;
};

View File

@ -1,7 +1,7 @@
From b6b784bac19b9ee68b7f7ee5855216b76ac118cd Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Wed, 15 Jan 2020 18:39:17 +0100
Subject: [PATCH 09/14] arm64: dts: allwinner: h6: tanix-tx6: enable emmc
Subject: [PATCH] arm64: dts: allwinner: h6: tanix-tx6: enable emmc
Tanix TX6 has 32 GiB eMMC. Add a node for it.

View File

@ -1,7 +1,7 @@
From ff190627e3986569a2516f36e218adcde02fc78b Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Sat, 24 Aug 2019 01:03:05 +0200
Subject: [PATCH 10/14] arm64: dts: allwinner: h6: tanix-tx6: enable ethernet
Subject: [PATCH] arm64: dts: allwinner: h6: tanix-tx6: enable ethernet
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---

View File

@ -1,7 +1,7 @@
From 483a90d0500c528b2faeed662c3209f779d43103 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sebastian Meyer <git-commit@mailhell.seb7.de>
Date: Mon, 3 Feb 2020 21:27:47 +0100
Subject: [PATCH 11/14] arm64: allwinner: h6: Enable USB3 for OrangePi Lite2
Subject: [PATCH] arm64: allwinner: h6: Enable USB3 for OrangePi Lite2
Signed-off-by: Sebastian Meyer <git-commit@mailhell.seb7.de>
---

View File

@ -1,9 +1,9 @@
From 4b723d23c444ae9dc85ecea51a1ae4de092ddf54 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20Gonz=C3=A1lez?=
<alejandro.gonzalez.correo@gmail.com>
Date: Sun, 25 Aug 2019 17:05:58 +0200
Subject: [PATCH 12/14] mmc: sunxi: fix unusuable eMMC on some H6 boards by
disabling DDR
Subject: [PATCH] mmc: sunxi: fix unusuable eMMC on some H6 boards by disabling
DDR
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

View File

@ -1,7 +1,7 @@
From 083e09f834e58cad72671e4df2136cf36c10aaa7 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Thu, 29 Oct 2020 21:04:24 +0100
Subject: [PATCH 13/14] pineh64 model b - bluetooth wip
Subject: [PATCH] pineh64 model b - bluetooth wip
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---

View File

@ -1,27 +0,0 @@
From 64954a507d442da5c2615897e6d35154c9c2f593 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Tue, 8 Dec 2020 19:48:39 -0600
Subject: [PATCH 14/14] hack to fix sun8i_dwmac
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1310,12 +1310,14 @@ static const struct of_device_id sun8i_d
};
MODULE_DEVICE_TABLE(of, sun8i_dwmac_match);
+static SIMPLE_DEV_PM_OPS(sun8i_dwmac_pm_ops, stmmac_suspend, stmmac_resume);
+
static struct platform_driver sun8i_dwmac_driver = {
.probe = sun8i_dwmac_probe,
.remove = stmmac_pltfr_remove,
.driver = {
.name = "dwmac-sun8i",
- .pm = &stmmac_pltfr_pm_ops,
+ .pm = &sun8i_dwmac_pm_ops,
.of_match_table = sun8i_dwmac_match,
},
};

View File

@ -0,0 +1,82 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 16 Jan 2021 01:58:22 -0600
Subject: [PATCH] allwinner: psci: Improve system shutdown/reset sequence
- When the SCPI shutdown/reset command returns success, the SCPI
implementation is still waiting for the CPU to enter WFI. Do that.
- Peform board-level poweroff before CPU poweroff. If there is a PMIC
available, it will turn everything off including the CPUs, so doing
CPU poweroff first is a waste of cycles.
- During poweroff, attempt to turn off the local CPU using the ARISC.
This should use slightly less power than just an infinite WFI.
- Drop the WFI in the reset failure path. The panic will hang anyway.
Change-Id: I897efecb3fe4e77a56041b97dd273156ec51ef8e
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
plat/allwinner/common/sunxi_pm.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 03985f40be55..038f2b7edb2f 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -125,24 +125,29 @@ static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
static void __dead2 sunxi_system_off(void)
{
+ u_register_t mpidr = read_mpidr();
+
gicv2_cpuif_disable();
if (scpi_available) {
/* Send the power down request to the SCP */
uint32_t ret = scpi_sys_power_state(scpi_system_shutdown);
- if (ret != SCP_OK)
- ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
+ if (ret == SCP_OK)
+ wfi();
+
+ ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
}
- /* Turn off all secondary CPUs */
- sunxi_disable_secondary_cpus(read_mpidr());
-
+ /* Attempt to power down the board (may not return) */
sunxi_power_down();
- udelay(1000);
+ /* Turn off all CPUs */
+ sunxi_disable_secondary_cpus(mpidr);
+ sunxi_cpu_off(mpidr);
+ wfi();
+
ERROR("PSCI: Cannot turn off system, halting\n");
- wfi();
panic();
}
@@ -154,8 +159,10 @@ static void __dead2 sunxi_system_reset(void)
/* Send the system reset request to the SCP */
uint32_t ret = scpi_sys_power_state(scpi_system_reboot);
- if (ret != SCP_OK)
- ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret);
+ if (ret == SCP_OK)
+ wfi();
+
+ ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret);
}
/* Reset the whole system when the watchdog times out */
@@ -166,7 +173,6 @@ static void __dead2 sunxi_system_reset(void)
mdelay(1000);
ERROR("PSCI: System reset failed\n");
- wfi();
panic();
}

View File

@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 2 Jan 2021 15:52:27 -0600
Subject: [PATCH] Input: axp20x-pek - allow wakeup after shutdown
While the AXP20x PMIC handles the power button itself after shutting
down, it is not always possible to use the PMIC's built-in shutdown
feature, such as when other wakeup sources are needed (for example, an
IR remote or wake-on-LAN) that require firmware support. In that case,
the PMIC remains on, but suspended, until the board is powered back on.
During this "fake" off state, IRQ configuration is similar to system
sleep, where enable_irq_wake() must be call on an IRQ for it to be
wakeup capable. Run the suspend callback to arm the power button IRQs
during the shutdown process, so the power button works in this state.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/input/misc/axp20x-pek.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/input/misc/axp20x-pek.c
+++ b/drivers/input/misc/axp20x-pek.c
@@ -354,7 +354,7 @@ static int axp20x_pek_probe(struct platf
return 0;
}
-static int __maybe_unused axp20x_pek_suspend(struct device *dev)
+static int axp20x_pek_suspend(struct device *dev)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
@@ -413,6 +413,11 @@ static const struct dev_pm_ops axp20x_pe
#endif
};
+static void axp20x_pek_shutdown(struct platform_device *pdev)
+{
+ axp20x_pek_suspend(&pdev->dev);
+}
+
static const struct platform_device_id axp_pek_id_match[] = {
{
.name = "axp20x-pek",
@@ -428,6 +433,7 @@ MODULE_DEVICE_TABLE(platform, axp_pek_id
static struct platform_driver axp20x_pek_driver = {
.probe = axp20x_pek_probe,
+ .shutdown = axp20x_pek_shutdown,
.id_table = axp_pek_id_match,
.driver = {
.name = "axp20x-pek",

View File

@ -1,137 +0,0 @@
From 49d3e172a2e06e7670c508e1d960282d40e7237e Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 12 Feb 2020 22:58:30 -0600
Subject: [PATCH 01/31] i2c: mv64xxx: Add runtime PM support
To save power, gate the clock when the bus is inactive, and during
system suspend. Also reset the controller during system suspend, since
it may be used by platform firmware, and we don't want to make any
assumptions about the hardware state at resume.
On some platforms, specifically Allwinner A13/A20, gating the clock
implicitly resets the module as well. Since the module already needs to
be reset after some suspend/resume cycles, it is simple enough to reset
it during every runtime suspend/resume.
Because the bus may be used by wakeup source IRQ threads, it needs to be
functional as soon as IRQs are enabled. Thus, its system PM hooks need
to run in the noirq phase.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/i2c/busses/i2c-mv64xxx.c | 52 ++++++++++++++++++++++++++------
1 file changed, 42 insertions(+), 10 deletions(-)
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/mv643xx_i2c.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -713,6 +714,10 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
int rc, ret = num;
+ rc = pm_runtime_get_sync(&adap->dev);
+ if (rc < 0)
+ return rc;
+
BUG_ON(drv_data->msgs != NULL);
drv_data->msgs = msgs;
drv_data->num_msgs = num;
@@ -728,6 +733,9 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada
drv_data->num_msgs = 0;
drv_data->msgs = NULL;
+ pm_runtime_mark_last_busy(&adap->dev);
+ pm_runtime_put_autosuspend(&adap->dev);
+
return ret;
}
@@ -950,6 +958,11 @@ mv64xxx_i2c_probe(struct platform_device
goto exit_free_irq;
}
+ pm_runtime_set_active(&pd->dev);
+ pm_runtime_set_autosuspend_delay(&pd->dev, 1000);
+ pm_runtime_use_autosuspend(&pd->dev);
+ pm_runtime_enable(&pd->dev);
+
return 0;
exit_free_irq:
@@ -968,40 +981,59 @@ mv64xxx_i2c_remove(struct platform_devic
{
struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(dev);
+ pm_runtime_get_sync(&dev->dev);
+
i2c_del_adapter(&drv_data->adapter);
free_irq(drv_data->irq, drv_data);
reset_control_assert(drv_data->rstc);
clk_disable_unprepare(drv_data->reg_clk);
clk_disable_unprepare(drv_data->clk);
+ pm_runtime_put_noidle(&dev->dev);
+ pm_runtime_disable(&dev->dev);
+
+ return 0;
+}
+
+static int __maybe_unused mv64xxx_i2c_runtime_suspend(struct device *dev)
+{
+ struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
+
+ reset_control_assert(drv_data->rstc);
+ clk_disable_unprepare(drv_data->reg_clk);
+ clk_disable_unprepare(drv_data->clk);
+
return 0;
}
-#ifdef CONFIG_PM
-static int mv64xxx_i2c_resume(struct device *dev)
+static int __maybe_unused mv64xxx_i2c_runtime_resume(struct device *dev)
{
struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
+ if (!IS_ERR(drv_data->clk))
+ clk_prepare_enable(drv_data->clk);
+ if (!IS_ERR(drv_data->reg_clk))
+ clk_prepare_enable(drv_data->reg_clk);
+ reset_control_reset(drv_data->rstc);
+
mv64xxx_i2c_hw_init(drv_data);
return 0;
}
-static const struct dev_pm_ops mv64xxx_i2c_pm = {
- .resume = mv64xxx_i2c_resume,
+static const struct dev_pm_ops mv64xxx_i2c_pm_ops = {
+ SET_RUNTIME_PM_OPS(mv64xxx_i2c_runtime_suspend,
+ mv64xxx_i2c_runtime_resume, NULL)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
};
-#define mv64xxx_i2c_pm_ops (&mv64xxx_i2c_pm)
-#else
-#define mv64xxx_i2c_pm_ops NULL
-#endif
-
static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe,
.remove = mv64xxx_i2c_remove,
.driver = {
.name = MV64XXX_I2C_CTLR_NAME,
- .pm = mv64xxx_i2c_pm_ops,
+ .pm = &mv64xxx_i2c_pm_ops,
.of_match_table = mv64xxx_i2c_of_match_table,
},
};

View File

@ -0,0 +1,93 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:17:41 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Fix probe error handling
stmmac_pltfr_remove does three things in one function, making it
inapproprate for unwinding the steps in the probe function. Currently,
a failure before the call to stmmac_dvr_probe would leak OF node
references due to missing a call to stmmac_remove_config_dt. And an
error in stmmac_dvr_probe would cause the driver to attempt to remove a
netdevice that was never added. Fix these by reordering the init and
splitting out the error handling steps.
Fixes: 9f93ac8d4085 ("net-next: stmmac: Add dwmac-sun8i")
Fixes: 40a1dcee2d18 ("net: ethernet: dwmac-sun8i: Use the correct function in exit path")
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 25 +++++++++++--------
1 file changed, 15 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1134,10 +1134,6 @@ static int sun8i_dwmac_probe(struct plat
if (ret)
return ret;
- plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
- if (IS_ERR(plat_dat))
- return PTR_ERR(plat_dat);
-
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
if (!gmac)
return -ENOMEM;
@@ -1201,11 +1197,15 @@ static int sun8i_dwmac_probe(struct plat
ret = of_get_phy_mode(dev->of_node, &interface);
if (ret)
return -EINVAL;
- plat_dat->interface = interface;
+
+ plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
+ if (IS_ERR(plat_dat))
+ return PTR_ERR(plat_dat);
/* platform data specifying hardware features and callbacks.
* hardware features were copied from Allwinner drivers.
*/
+ plat_dat->interface = interface;
plat_dat->rx_coe = STMMAC_RX_COE_TYPE2;
plat_dat->tx_coe = 1;
plat_dat->has_sun8i = true;
@@ -1216,7 +1216,7 @@ static int sun8i_dwmac_probe(struct plat
ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
if (ret)
- return ret;
+ goto dwmac_deconfig;
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
@@ -1230,7 +1230,7 @@ static int sun8i_dwmac_probe(struct plat
if (gmac->variant->soc_has_internal_phy) {
ret = get_ephy_nodes(priv);
if (ret)
- goto dwmac_exit;
+ goto dwmac_remove;
ret = sun8i_dwmac_register_mdio_mux(priv);
if (ret) {
dev_err(&pdev->dev, "Failed to register mux\n");
@@ -1239,15 +1239,20 @@ static int sun8i_dwmac_probe(struct plat
} else {
ret = sun8i_dwmac_reset(priv);
if (ret)
- goto dwmac_exit;
+ goto dwmac_remove;
}
return ret;
dwmac_mux:
sun8i_dwmac_unset_syscon(gmac);
+dwmac_remove:
+ stmmac_dvr_remove(&pdev->dev);
dwmac_exit:
- stmmac_pltfr_remove(pdev);
-return ret;
+ sun8i_dwmac_exit(pdev, gmac);
+dwmac_deconfig:
+ stmmac_remove_config_dt(pdev, plat_dat);
+
+ return ret;
}
static const struct of_device_id sun8i_dwmac_match[] = {

View File

@ -0,0 +1,87 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:17:42 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Balance internal PHY resource
references
While stmmac_pltfr_remove calls sun8i_dwmac_exit, the sun8i_dwmac_init
and sun8i_dwmac_exit functions are also called by the stmmac_platform
suspend/resume callbacks. They may be called many times during the
device's lifetime and should not release resources used by the driver.
Furthermore, there was no error handling in case registering the MDIO
mux failed during probe, and the EPHY clock was never released at all.
Fix all of these issues by moving the deinitialization code to a driver
removal callback. Also ensure the EPHY is powered down before removal.
Fixes: 634db83b8265 ("net: stmmac: dwmac-sun8i: Handle integrated/external MDIOs")
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 27 ++++++++++++++-----
1 file changed, 21 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1004,17 +1004,12 @@ static void sun8i_dwmac_exit(struct plat
struct sunxi_priv_data *gmac = priv;
if (gmac->variant->soc_has_internal_phy) {
- /* sun8i_dwmac_exit could be called with mdiomux uninit */
- if (gmac->mux_handle)
- mdio_mux_uninit(gmac->mux_handle);
if (gmac->internal_phy_powered)
sun8i_dwmac_unpower_internal_phy(gmac);
}
sun8i_dwmac_unset_syscon(gmac);
- reset_control_put(gmac->rst_ephy);
-
clk_disable_unprepare(gmac->tx_clk);
if (gmac->regulator)
@@ -1244,6 +1239,8 @@ static int sun8i_dwmac_probe(struct plat
return ret;
dwmac_mux:
+ reset_control_put(gmac->rst_ephy);
+ clk_put(gmac->ephy_clk);
sun8i_dwmac_unset_syscon(gmac);
dwmac_remove:
stmmac_dvr_remove(&pdev->dev);
@@ -1255,6 +1252,24 @@ dwmac_deconfig:
return ret;
}
+static int sun8i_dwmac_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
+
+ if (gmac->variant->soc_has_internal_phy) {
+ mdio_mux_uninit(gmac->mux_handle);
+ sun8i_dwmac_unpower_internal_phy(gmac);
+ reset_control_put(gmac->rst_ephy);
+ clk_put(gmac->ephy_clk);
+ }
+
+ stmmac_pltfr_remove(pdev);
+
+ return 0;
+}
+
static const struct of_device_id sun8i_dwmac_match[] = {
{ .compatible = "allwinner,sun8i-h3-emac",
.data = &emac_variant_h3 },
@@ -1274,7 +1289,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dwmac_matc
static struct platform_driver sun8i_dwmac_driver = {
.probe = sun8i_dwmac_probe,
- .remove = stmmac_pltfr_remove,
+ .remove = sun8i_dwmac_remove,
.driver = {
.name = "dwmac-sun8i",
.pm = &stmmac_pltfr_pm_ops,

View File

@ -0,0 +1,108 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:17:43 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Balance internal PHY power
sun8i_dwmac_exit calls sun8i_dwmac_unpower_internal_phy, but
sun8i_dwmac_init did not call sun8i_dwmac_power_internal_phy. This
caused PHY power to remain off after a suspend/resume cycle. Fix this by
recording if PHY power should be restored, and if so, restoring it.
Fixes: 634db83b8265 ("net: stmmac: dwmac-sun8i: Handle integrated/external MDIOs")
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 31 ++++++++++++++-----
1 file changed, 23 insertions(+), 8 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -64,6 +64,7 @@ struct emac_variant {
* @variant: reference to the current board variant
* @regmap: regmap for using the syscon
* @internal_phy_powered: Does the internal PHY is enabled
+ * @use_internal_phy: Is the internal PHY selected for use
* @mux_handle: Internal pointer used by mdio-mux lib
*/
struct sunxi_priv_data {
@@ -74,6 +75,7 @@ struct sunxi_priv_data {
const struct emac_variant *variant;
struct regmap_field *regmap_field;
bool internal_phy_powered;
+ bool use_internal_phy;
void *mux_handle;
};
@@ -539,8 +541,11 @@ static const struct stmmac_dma_ops sun8i
.dma_interrupt = sun8i_dwmac_dma_interrupt,
};
+static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);
+
static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
{
+ struct net_device *ndev = platform_get_drvdata(pdev);
struct sunxi_priv_data *gmac = priv;
int ret;
@@ -554,13 +559,25 @@ static int sun8i_dwmac_init(struct platf
ret = clk_prepare_enable(gmac->tx_clk);
if (ret) {
- if (gmac->regulator)
- regulator_disable(gmac->regulator);
dev_err(&pdev->dev, "Could not enable AHB clock\n");
- return ret;
+ goto err_disable_regulator;
+ }
+
+ if (gmac->use_internal_phy) {
+ ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
+ if (ret)
+ goto err_disable_clk;
}
return 0;
+
+err_disable_clk:
+ clk_disable_unprepare(gmac->tx_clk);
+err_disable_regulator:
+ if (gmac->regulator)
+ regulator_disable(gmac->regulator);
+
+ return ret;
}
static void sun8i_dwmac_core_init(struct mac_device_info *hw,
@@ -831,7 +848,6 @@ static int mdio_mux_syscon_switch_fn(int
struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
u32 reg, val;
int ret = 0;
- bool need_power_ephy = false;
if (current_child ^ desired_child) {
regmap_field_read(gmac->regmap_field, &reg);
@@ -839,13 +855,12 @@ static int mdio_mux_syscon_switch_fn(int
case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID:
dev_info(priv->device, "Switch mux to internal PHY");
val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT;
-
- need_power_ephy = true;
+ gmac->use_internal_phy = true;
break;
case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID:
dev_info(priv->device, "Switch mux to external PHY");
val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN;
- need_power_ephy = false;
+ gmac->use_internal_phy = false;
break;
default:
dev_err(priv->device, "Invalid child ID %x\n",
@@ -853,7 +868,7 @@ static int mdio_mux_syscon_switch_fn(int
return -EINVAL;
}
regmap_field_write(gmac->regmap_field, val);
- if (need_power_ephy) {
+ if (gmac->use_internal_phy) {
ret = sun8i_dwmac_power_internal_phy(priv);
if (ret)
return ret;

View File

@ -0,0 +1,204 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:17:44 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Balance syscon (de)initialization
Previously, sun8i_dwmac_set_syscon was called from a chain of functions
in several different files:
sun8i_dwmac_probe
stmmac_dvr_probe
stmmac_hw_init
stmmac_hwif_init
sun8i_dwmac_setup
sun8i_dwmac_set_syscon
which made the lifetime of the syscon values hard to reason about. Part
of the problem is that there is no similar platform driver callback from
stmmac_dvr_remove. As a result, the driver unset the syscon value in
sun8i_dwmac_exit, but this leaves it uninitialized after a suspend/
resume cycle. It was also unset a second time (outside sun8i_dwmac_exit)
in the probe error path.
Move the init to the earliest available place in sun8i_dwmac_probe
(after stmmac_probe_config_dt, which initializes plat_dat), and the
deinit to the corresponding position in the cleanup order.
Since priv is not filled in until stmmac_dvr_probe, this requires
changing the sun8i_dwmac_set_syscon parameters to priv's two relevant
members.
Fixes: 9f93ac8d4085 ("net-next: stmmac: Add dwmac-sun8i")
Fixes: 634db83b8265 ("net: stmmac: dwmac-sun8i: Handle integrated/external MDIOs")
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 50 +++++++++----------
1 file changed, 25 insertions(+), 25 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -898,22 +898,23 @@ static int sun8i_dwmac_register_mdio_mux
return ret;
}
-static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
+static int sun8i_dwmac_set_syscon(struct device *dev,
+ struct plat_stmmacenet_data *plat)
{
- struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
- struct device_node *node = priv->device->of_node;
+ struct sunxi_priv_data *gmac = plat->bsp_priv;
+ struct device_node *node = dev->of_node;
int ret;
u32 reg, val;
ret = regmap_field_read(gmac->regmap_field, &val);
if (ret) {
- dev_err(priv->device, "Fail to read from regmap field.\n");
+ dev_err(dev, "Fail to read from regmap field.\n");
return ret;
}
reg = gmac->variant->default_syscon_value;
if (reg != val)
- dev_warn(priv->device,
+ dev_warn(dev,
"Current syscon value is not the default %x (expect %x)\n",
val, reg);
@@ -926,9 +927,9 @@ static int sun8i_dwmac_set_syscon(struct
/* Force EPHY xtal frequency to 24MHz. */
reg |= H3_EPHY_CLK_SEL;
- ret = of_mdio_parse_addr(priv->device, priv->plat->phy_node);
+ ret = of_mdio_parse_addr(dev, plat->phy_node);
if (ret < 0) {
- dev_err(priv->device, "Could not parse MDIO addr\n");
+ dev_err(dev, "Could not parse MDIO addr\n");
return ret;
}
/* of_mdio_parse_addr returns a valid (0 ~ 31) PHY
@@ -944,17 +945,17 @@ static int sun8i_dwmac_set_syscon(struct
if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) {
if (val % 100) {
- dev_err(priv->device, "tx-delay must be a multiple of 100\n");
+ dev_err(dev, "tx-delay must be a multiple of 100\n");
return -EINVAL;
}
val /= 100;
- dev_dbg(priv->device, "set tx-delay to %x\n", val);
+ dev_dbg(dev, "set tx-delay to %x\n", val);
if (val <= gmac->variant->tx_delay_max) {
reg &= ~(gmac->variant->tx_delay_max <<
SYSCON_ETXDC_SHIFT);
reg |= (val << SYSCON_ETXDC_SHIFT);
} else {
- dev_err(priv->device, "Invalid TX clock delay: %d\n",
+ dev_err(dev, "Invalid TX clock delay: %d\n",
val);
return -EINVAL;
}
@@ -962,17 +963,17 @@ static int sun8i_dwmac_set_syscon(struct
if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) {
if (val % 100) {
- dev_err(priv->device, "rx-delay must be a multiple of 100\n");
+ dev_err(dev, "rx-delay must be a multiple of 100\n");
return -EINVAL;
}
val /= 100;
- dev_dbg(priv->device, "set rx-delay to %x\n", val);
+ dev_dbg(dev, "set rx-delay to %x\n", val);
if (val <= gmac->variant->rx_delay_max) {
reg &= ~(gmac->variant->rx_delay_max <<
SYSCON_ERXDC_SHIFT);
reg |= (val << SYSCON_ERXDC_SHIFT);
} else {
- dev_err(priv->device, "Invalid RX clock delay: %d\n",
+ dev_err(dev, "Invalid RX clock delay: %d\n",
val);
return -EINVAL;
}
@@ -983,7 +984,7 @@ static int sun8i_dwmac_set_syscon(struct
if (gmac->variant->support_rmii)
reg &= ~SYSCON_RMII_EN;
- switch (priv->plat->interface) {
+ switch (plat->interface) {
case PHY_INTERFACE_MODE_MII:
/* default */
break;
@@ -997,8 +998,8 @@ static int sun8i_dwmac_set_syscon(struct
reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII;
break;
default:
- dev_err(priv->device, "Unsupported interface mode: %s",
- phy_modes(priv->plat->interface));
+ dev_err(dev, "Unsupported interface mode: %s",
+ phy_modes(plat->interface));
return -EINVAL;
}
@@ -1023,8 +1024,6 @@ static void sun8i_dwmac_exit(struct plat
sun8i_dwmac_unpower_internal_phy(gmac);
}
- sun8i_dwmac_unset_syscon(gmac);
-
clk_disable_unprepare(gmac->tx_clk);
if (gmac->regulator)
@@ -1059,16 +1058,11 @@ static struct mac_device_info *sun8i_dwm
{
struct mac_device_info *mac;
struct stmmac_priv *priv = ppriv;
- int ret;
mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
if (!mac)
return NULL;
- ret = sun8i_dwmac_set_syscon(priv);
- if (ret)
- return NULL;
-
mac->pcsr = priv->ioaddr;
mac->mac = &sun8i_dwmac_ops;
mac->dma = &sun8i_dwmac_dma_ops;
@@ -1224,10 +1218,14 @@ static int sun8i_dwmac_probe(struct plat
plat_dat->exit = sun8i_dwmac_exit;
plat_dat->setup = sun8i_dwmac_setup;
- ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
+ ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat);
if (ret)
goto dwmac_deconfig;
+ ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
+ if (ret)
+ goto dwmac_syscon;
+
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
goto dwmac_exit;
@@ -1256,11 +1254,12 @@ static int sun8i_dwmac_probe(struct plat
dwmac_mux:
reset_control_put(gmac->rst_ephy);
clk_put(gmac->ephy_clk);
- sun8i_dwmac_unset_syscon(gmac);
dwmac_remove:
stmmac_dvr_remove(&pdev->dev);
dwmac_exit:
sun8i_dwmac_exit(pdev, gmac);
+dwmac_syscon:
+ sun8i_dwmac_unset_syscon(gmac);
dwmac_deconfig:
stmmac_remove_config_dt(pdev, plat_dat);
@@ -1281,6 +1280,7 @@ static int sun8i_dwmac_remove(struct pla
}
stmmac_pltfr_remove(pdev);
+ sun8i_dwmac_unset_syscon(gmac);
return 0;
}

View File

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:25:38 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Return void from PHY unpower
This is a deinitialization function that always returned zero, and that
return value was always ignored. Have it return void instead.
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -820,15 +820,14 @@ static int sun8i_dwmac_power_internal_ph
return 0;
}
-static int sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
+static void sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
{
if (!gmac->internal_phy_powered)
- return 0;
+ return;
clk_disable_unprepare(gmac->ephy_clk);
reset_control_assert(gmac->rst_ephy);
gmac->internal_phy_powered = false;
- return 0;
}
/* MDIO multiplexing switch function

View File

@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:25:39 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Remove unnecessary PHY power check
sun8i_dwmac_unpower_internal_phy already checks if the PHY is powered,
so there is no need to do it again here.
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1018,10 +1018,8 @@ static void sun8i_dwmac_exit(struct plat
{
struct sunxi_priv_data *gmac = priv;
- if (gmac->variant->soc_has_internal_phy) {
- if (gmac->internal_phy_powered)
- sun8i_dwmac_unpower_internal_phy(gmac);
- }
+ if (gmac->variant->soc_has_internal_phy)
+ sun8i_dwmac_unpower_internal_phy(gmac);
clk_disable_unprepare(gmac->tx_clk);

View File

@ -1,27 +0,0 @@
From fe3a4fd11558fac2ac10928d217b21ff2f67483f Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 21:56:59 -0600
Subject: [PATCH 08/31] bus: sunxi-rsb: Always check register address validity
The register address was already validated for read operations before
being truncated to a u8. Write operations have the same set of possible
addresses, and the address is being truncated from u32 to u8 here as
well, so the same check is needed.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/bus/sunxi-rsb.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -414,6 +414,9 @@ static int regmap_sunxi_rsb_reg_write(vo
struct sunxi_rsb_ctx *ctx = context;
struct sunxi_rsb_device *rdev = ctx->rdev;
+ if (reg > 0xff)
+ return -EINVAL;
+
return sunxi_rsb_write(rdev->rsb, rdev->rtaddr, reg, &val, ctx->size);
}

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:25:40 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Use reset_control_reset
Use the appropriate function instead of reimplementing it,
and update the error message to match the code.
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -806,11 +806,9 @@ static int sun8i_dwmac_power_internal_ph
/* Make sure the EPHY is properly reseted, as U-Boot may leave
* it at deasserted state, and thus it may fail to reset EMAC.
*/
- reset_control_assert(gmac->rst_ephy);
-
- ret = reset_control_deassert(gmac->rst_ephy);
+ ret = reset_control_reset(gmac->rst_ephy);
if (ret) {
- dev_err(priv->device, "Cannot deassert internal phy\n");
+ dev_err(priv->device, "Cannot reset internal PHY\n");
clk_disable_unprepare(gmac->ephy_clk);
return ret;
}

View File

@ -1,33 +0,0 @@
From febbd571f841fcf680f22148b0b5b24301fad5c1 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 22:09:08 -0600
Subject: [PATCH 09/31] bus: sunxi-rsb: Use devm_platform_ioremap_resource
This simplifies the code and removes the need for a "struct resource".
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/bus/sunxi-rsb.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -627,7 +627,6 @@ static int sunxi_rsb_probe(struct platfo
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct resource *r;
struct sunxi_rsb *rsb;
unsigned long p_clk_freq;
u32 clk_delay, clk_freq = 3000000;
@@ -648,8 +647,8 @@ static int sunxi_rsb_probe(struct platfo
rsb->dev = dev;
platform_set_drvdata(pdev, rsb);
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- rsb->regs = devm_ioremap_resource(dev, r);
+
+ rsb->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rsb->regs))
return PTR_ERR(rsb->regs);

View File

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:25:41 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Minor probe function cleanup
Adjust the spacing and use an explicit "return 0" in the success path
to make the function easier to parse.
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1227,6 +1227,7 @@ static int sun8i_dwmac_probe(struct plat
ndev = dev_get_drvdata(&pdev->dev);
priv = netdev_priv(ndev);
+
/* The mux must be registered after parent MDIO
* so after stmmac_dvr_probe()
*/
@@ -1245,7 +1246,8 @@ static int sun8i_dwmac_probe(struct plat
goto dwmac_remove;
}
- return ret;
+ return 0;
+
dwmac_mux:
reset_control_put(gmac->rst_ephy);
clk_put(gmac->ephy_clk);

View File

@ -1,208 +0,0 @@
From 0a9087b56ec06abe2ff7f4c2c2732677cec8793e Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 21:49:29 -0600
Subject: [PATCH 10/31] bus: sunxi-rsb: Precompute read/write commands and mask
Since we know the size of the transfer at context creation time, go
ahead and determine the commands used for reading and writing then,
instead of running through a switch statement for every read/write.
We can do the same thing for the read mask.
The context pointer could be passed directly to sunxi_rsb_read/write
to avoid adding more parameters (which would be spilled for mutex_lock).
That would make the regmap read/write wrappers even more trivial, so I
inlined sunxi_rsb_read/write into them.
I changed the error message to print the name of the device requesting
the regmap, not the RSB controller; I expect that to be more helpful
when tracking down the source of the error.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/bus/sunxi-rsb.c | 120 +++++++++++++++-------------------------
1 file changed, 44 insertions(+), 76 deletions(-)
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -311,41 +311,38 @@ static int _sunxi_rsb_run_xfer(struct su
return 0;
}
-static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
- u32 *buf, size_t len)
+/* RSB regmap functions */
+struct sunxi_rsb_ctx {
+ struct sunxi_rsb_device *rdev;
+ u32 mask;
+ u8 rd_cmd;
+ u8 wr_cmd;
+};
+
+static int regmap_sunxi_rsb_reg_read(void *context, unsigned int reg,
+ unsigned int *val)
{
- u32 cmd;
+ struct sunxi_rsb_ctx *ctx = context;
+ struct sunxi_rsb_device *rdev = ctx->rdev;
+ struct sunxi_rsb *rsb = rdev->rsb;
int ret;
- if (!buf)
+ if (!val)
return -EINVAL;
-
- switch (len) {
- case 1:
- cmd = RSB_CMD_RD8;
- break;
- case 2:
- cmd = RSB_CMD_RD16;
- break;
- case 4:
- cmd = RSB_CMD_RD32;
- break;
- default:
- dev_err(rsb->dev, "Invalid access width: %zd\n", len);
+ if (reg > 0xff)
return -EINVAL;
- }
mutex_lock(&rsb->lock);
- writel(addr, rsb->regs + RSB_ADDR);
- writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
- writel(cmd, rsb->regs + RSB_CMD);
+ writel(reg, rsb->regs + RSB_ADDR);
+ writel(RSB_DAR_RTA(rdev->rtaddr), rsb->regs + RSB_DAR);
+ writel(ctx->rd_cmd, rsb->regs + RSB_CMD);
ret = _sunxi_rsb_run_xfer(rsb);
if (ret)
goto unlock;
- *buf = readl(rsb->regs + RSB_DATA) & GENMASK(len * 8 - 1, 0);
+ *val = readl(rsb->regs + RSB_DATA) & ctx->mask;
unlock:
mutex_unlock(&rsb->lock);
@@ -353,36 +350,24 @@ unlock:
return ret;
}
-static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
- const u32 *buf, size_t len)
+static int regmap_sunxi_rsb_reg_write(void *context, unsigned int reg,
+ unsigned int val)
{
- u32 cmd;
+ struct sunxi_rsb_ctx *ctx = context;
+ struct sunxi_rsb_device *rdev = ctx->rdev;
+ struct sunxi_rsb *rsb = rdev->rsb;
int ret;
- if (!buf)
- return -EINVAL;
-
- switch (len) {
- case 1:
- cmd = RSB_CMD_WR8;
- break;
- case 2:
- cmd = RSB_CMD_WR16;
- break;
- case 4:
- cmd = RSB_CMD_WR32;
- break;
- default:
- dev_err(rsb->dev, "Invalid access width: %zd\n", len);
+ if (reg > 0xff)
return -EINVAL;
- }
mutex_lock(&rsb->lock);
- writel(addr, rsb->regs + RSB_ADDR);
- writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
- writel(*buf, rsb->regs + RSB_DATA);
- writel(cmd, rsb->regs + RSB_CMD);
+ writel(reg, rsb->regs + RSB_ADDR);
+ writel(RSB_DAR_RTA(rdev->rtaddr), rsb->regs + RSB_DAR);
+ writel(val, rsb->regs + RSB_DATA);
+ writel(ctx->wr_cmd, rsb->regs + RSB_CMD);
+
ret = _sunxi_rsb_run_xfer(rsb);
mutex_unlock(&rsb->lock);
@@ -390,36 +375,6 @@ static int sunxi_rsb_write(struct sunxi_
return ret;
}
-/* RSB regmap functions */
-struct sunxi_rsb_ctx {
- struct sunxi_rsb_device *rdev;
- int size;
-};
-
-static int regmap_sunxi_rsb_reg_read(void *context, unsigned int reg,
- unsigned int *val)
-{
- struct sunxi_rsb_ctx *ctx = context;
- struct sunxi_rsb_device *rdev = ctx->rdev;
-
- if (reg > 0xff)
- return -EINVAL;
-
- return sunxi_rsb_read(rdev->rsb, rdev->rtaddr, reg, val, ctx->size);
-}
-
-static int regmap_sunxi_rsb_reg_write(void *context, unsigned int reg,
- unsigned int val)
-{
- struct sunxi_rsb_ctx *ctx = context;
- struct sunxi_rsb_device *rdev = ctx->rdev;
-
- if (reg > 0xff)
- return -EINVAL;
-
- return sunxi_rsb_write(rdev->rsb, rdev->rtaddr, reg, &val, ctx->size);
-}
-
static void regmap_sunxi_rsb_free_ctx(void *context)
{
struct sunxi_rsb_ctx *ctx = context;
@@ -439,13 +394,24 @@ static struct sunxi_rsb_ctx *regmap_sunx
const struct regmap_config *config)
{
struct sunxi_rsb_ctx *ctx;
+ u8 rd_cmd, wr_cmd;
switch (config->val_bits) {
case 8:
+ rd_cmd = RSB_CMD_RD8;
+ wr_cmd = RSB_CMD_WR8;
+ break;
case 16:
+ rd_cmd = RSB_CMD_RD16;
+ wr_cmd = RSB_CMD_WR16;
+ break;
case 32:
+ rd_cmd = RSB_CMD_RD32;
+ wr_cmd = RSB_CMD_WR32;
break;
default:
+ dev_err(&rdev->dev, "Invalid RSB access width: %d\n",
+ config->val_bits);
return ERR_PTR(-EINVAL);
}
@@ -454,7 +420,9 @@ static struct sunxi_rsb_ctx *regmap_sunx
return ERR_PTR(-ENOMEM);
ctx->rdev = rdev;
- ctx->size = config->val_bits / 8;
+ ctx->mask = GENMASK(config->val_bits - 1, 0);
+ ctx->rd_cmd = rd_cmd;
+ ctx->wr_cmd = wr_cmd;
return ctx;
}

View File

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Jan 2021 05:25:42 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: Add a shutdown callback
The Ethernet MAC and PHY are usually major consumers of power on boards
which may not be able to fully power off (that have no PMIC). Powering
down the MAC and internal PHY saves power while these boards are "off".
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1282,6 +1282,15 @@ static int sun8i_dwmac_remove(struct pla
return 0;
}
+static void sun8i_dwmac_shutdown(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
+
+ sun8i_dwmac_exit(pdev, gmac);
+}
+
static const struct of_device_id sun8i_dwmac_match[] = {
{ .compatible = "allwinner,sun8i-h3-emac",
.data = &emac_variant_h3 },
@@ -1302,6 +1311,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dwmac_matc
static struct platform_driver sun8i_dwmac_driver = {
.probe = sun8i_dwmac_probe,
.remove = sun8i_dwmac_remove,
+ .shutdown = sun8i_dwmac_shutdown,
.driver = {
.name = "dwmac-sun8i",
.pm = &stmmac_pltfr_pm_ops,

View File

@ -0,0 +1,237 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 12 Feb 2020 22:58:30 -0600
Subject: [PATCH] i2c: mv64xxx: Add runtime PM support
To save power, gate the clock when the bus is inactive, during system
sleep, and during shutdown. On some platforms, specifically Allwinner
A13/A20, gating the clock implicitly resets the module as well. Since
the module already needs to be reset after some suspend/resume cycles,
it is simple enough to reset it during every runtime suspend/resume.
Because the bus may be used by wakeup source IRQ threads, it needs to
be functional as soon as IRQs are enabled. Thus, its system PM hooks
need to run in the noirq phase.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/i2c/busses/i2c-mv64xxx.c | 118 ++++++++++++++++++++-----------
1 file changed, 77 insertions(+), 41 deletions(-)
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/mv643xx_i2c.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -713,6 +714,10 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
int rc, ret = num;
+ rc = pm_runtime_resume_and_get(&adap->dev);
+ if (rc)
+ return rc;
+
BUG_ON(drv_data->msgs != NULL);
drv_data->msgs = msgs;
drv_data->num_msgs = num;
@@ -728,6 +733,9 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada
drv_data->num_msgs = 0;
drv_data->msgs = NULL;
+ pm_runtime_mark_last_busy(&adap->dev);
+ pm_runtime_put_autosuspend(&adap->dev);
+
return ret;
}
@@ -824,7 +832,6 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat
rc = PTR_ERR(drv_data->rstc);
goto out;
}
- reset_control_deassert(drv_data->rstc);
/* Its not yet defined how timeouts will be specified in device tree.
* So hard code the value to 1 second.
@@ -871,6 +878,32 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat
#endif /* CONFIG_OF */
static int
+mv64xxx_i2c_runtime_suspend(struct device *dev)
+{
+ struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
+
+ reset_control_assert(drv_data->rstc);
+ clk_disable_unprepare(drv_data->reg_clk);
+ clk_disable_unprepare(drv_data->clk);
+
+ return 0;
+}
+
+static int
+mv64xxx_i2c_runtime_resume(struct device *dev)
+{
+ struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
+
+ clk_prepare_enable(drv_data->clk);
+ clk_prepare_enable(drv_data->reg_clk);
+ reset_control_reset(drv_data->rstc);
+
+ mv64xxx_i2c_hw_init(drv_data);
+
+ return 0;
+}
+
+static int
mv64xxx_i2c_probe(struct platform_device *pd)
{
struct mv64xxx_i2c_data *drv_data;
@@ -897,18 +930,22 @@ mv64xxx_i2c_probe(struct platform_device
/* Not all platforms have clocks */
drv_data->clk = devm_clk_get(&pd->dev, NULL);
- if (PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- if (!IS_ERR(drv_data->clk))
- clk_prepare_enable(drv_data->clk);
+ if (IS_ERR(drv_data->clk)) {
+ if (PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ drv_data->clk = NULL;
+ }
drv_data->reg_clk = devm_clk_get(&pd->dev, "reg");
- if (PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- if (!IS_ERR(drv_data->reg_clk))
- clk_prepare_enable(drv_data->reg_clk);
+ if (IS_ERR(drv_data->reg_clk)) {
+ if (PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ drv_data->reg_clk = NULL;
+ }
drv_data->irq = platform_get_irq(pd, 0);
+ if (drv_data->irq < 0)
+ return drv_data->irq;
if (pdata) {
drv_data->freq_m = pdata->freq_m;
@@ -919,11 +956,7 @@ mv64xxx_i2c_probe(struct platform_device
} else if (pd->dev.of_node) {
rc = mv64xxx_of_config(drv_data, &pd->dev);
if (rc)
- goto exit_clk;
- }
- if (drv_data->irq < 0) {
- rc = drv_data->irq;
- goto exit_reset;
+ return rc;
}
drv_data->adapter.dev.parent = &pd->dev;
@@ -935,7 +968,14 @@ mv64xxx_i2c_probe(struct platform_device
platform_set_drvdata(pd, drv_data);
i2c_set_adapdata(&drv_data->adapter, drv_data);
- mv64xxx_i2c_hw_init(drv_data);
+ pm_runtime_set_autosuspend_delay(&pd->dev, MSEC_PER_SEC);
+ pm_runtime_use_autosuspend(&pd->dev);
+ pm_runtime_enable(&pd->dev);
+ if (!pm_runtime_enabled(&pd->dev)) {
+ rc = mv64xxx_i2c_runtime_resume(&pd->dev);
+ if (rc)
+ goto exit_disable_pm;
+ }
rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
MV64XXX_I2C_CTLR_NAME, drv_data);
@@ -943,7 +983,7 @@ mv64xxx_i2c_probe(struct platform_device
dev_err(&drv_data->adapter.dev,
"mv64xxx: Can't register intr handler irq%d: %d\n",
drv_data->irq, rc);
- goto exit_reset;
+ goto exit_disable_pm;
} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
dev_err(&drv_data->adapter.dev,
"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
@@ -954,54 +994,50 @@ mv64xxx_i2c_probe(struct platform_device
exit_free_irq:
free_irq(drv_data->irq, drv_data);
-exit_reset:
- reset_control_assert(drv_data->rstc);
-exit_clk:
- clk_disable_unprepare(drv_data->reg_clk);
- clk_disable_unprepare(drv_data->clk);
+exit_disable_pm:
+ pm_runtime_disable(&pd->dev);
+ if (!pm_runtime_status_suspended(&pd->dev))
+ mv64xxx_i2c_runtime_suspend(&pd->dev);
return rc;
}
static int
-mv64xxx_i2c_remove(struct platform_device *dev)
+mv64xxx_i2c_remove(struct platform_device *pd)
{
- struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(dev);
+ struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(pd);
i2c_del_adapter(&drv_data->adapter);
free_irq(drv_data->irq, drv_data);
- reset_control_assert(drv_data->rstc);
- clk_disable_unprepare(drv_data->reg_clk);
- clk_disable_unprepare(drv_data->clk);
+ pm_runtime_disable(&pd->dev);
+ if (!pm_runtime_status_suspended(&pd->dev))
+ mv64xxx_i2c_runtime_suspend(&pd->dev);
return 0;
}
-#ifdef CONFIG_PM
-static int mv64xxx_i2c_resume(struct device *dev)
+static void
+mv64xxx_i2c_shutdown(struct platform_device *pd)
{
- struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev);
-
- mv64xxx_i2c_hw_init(drv_data);
-
- return 0;
+ pm_runtime_disable(&pd->dev);
+ if (!pm_runtime_status_suspended(&pd->dev))
+ mv64xxx_i2c_runtime_suspend(&pd->dev);
}
-static const struct dev_pm_ops mv64xxx_i2c_pm = {
- .resume = mv64xxx_i2c_resume,
+static const struct dev_pm_ops mv64xxx_i2c_pm_ops = {
+ SET_RUNTIME_PM_OPS(mv64xxx_i2c_runtime_suspend,
+ mv64xxx_i2c_runtime_resume, NULL)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
};
-#define mv64xxx_i2c_pm_ops (&mv64xxx_i2c_pm)
-#else
-#define mv64xxx_i2c_pm_ops NULL
-#endif
-
static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe,
.remove = mv64xxx_i2c_remove,
+ .shutdown = mv64xxx_i2c_shutdown,
.driver = {
.name = MV64XXX_I2C_CTLR_NAME,
- .pm = mv64xxx_i2c_pm_ops,
+ .pm = &mv64xxx_i2c_pm_ops,
.of_match_table = mv64xxx_i2c_of_match_table,
},
};

View File

@ -1,7 +1,7 @@
From 0d476c62bcc132f66dc69342c2a90bba6d7128fe Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 10 Jan 2021 00:41:23 -0600
Subject: [PATCH 1/4] media: sunxi-cir: Skip register writes during remove
Subject: [PATCH] media: sunxi-cir: Skip register writes during remove
These writes occur after the device is already put back in reset, so
they never had any effect.

View File

@ -1,7 +1,7 @@
From c7bc741a2aec36d9f87a99ef098db88825d5ef79 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 10 Jan 2021 00:43:19 -0600
Subject: [PATCH 2/4] media: sunxi-cir: Remove unnecessary spinlock
Subject: [PATCH] media: sunxi-cir: Remove unnecessary spinlock
Only one register, SUNXI_IR_CIR_REG, is written from outside the
interrupt handler, and that register is not written from inside it.

View File

@ -1,7 +1,7 @@
From c0009aa415ef085c8f31ddd68b873f195a77f3c4 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 10 Jan 2021 00:50:32 -0600
Subject: [PATCH 3/4] media: sunxi-cir: Factor out hardware initialization
Subject: [PATCH] media: sunxi-cir: Factor out hardware initialization
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

View File

@ -1,69 +0,0 @@
From 3c8535aee4f58ffeae01dd4d6e32479e9fd68a7e Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 22:58:21 -0600
Subject: [PATCH 15/31] bus: sunxi-rsb: Make interrupt handling more robust
The RSB controller has two registers for controlling interrupt inputs:
RSB_INTE, which has bits for each possible interrupt, and the global
interrupt enable bit in RSB_CTRL.
Currently, we enable the bits in RSB_INTE before each transfer, but this
is unnecessary because we never disable them. Move the initialization of
RSB_INTE so it is done only once.
We also set the global interrupt enable bit before each transfer. Unlike
other bits in RSB_CTRL, this bit is cleared by writing a zero. Thus, we
clear the bit in the post-timeout cleanup code, but that is not
documented, so note that in the comment. However, in the success/error
path (when an IRQ is received), we do not disable further interrupts.
Add a register write to do just that.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/bus/sunxi-rsb.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -276,8 +276,6 @@ static int _sunxi_rsb_run_xfer(struct su
reinit_completion(&rsb->complete);
- writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
- rsb->regs + RSB_INTE);
writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
rsb->regs + RSB_CTRL);
@@ -285,7 +283,7 @@ static int _sunxi_rsb_run_xfer(struct su
msecs_to_jiffies(100))) {
dev_dbg(rsb->dev, "RSB timeout\n");
- /* abort the transfer */
+ /* abort the transfer and disable interrupts */
writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL);
/* clear any interrupt flags */
@@ -460,7 +458,8 @@ static irqreturn_t sunxi_rsb_irq(int irq
status = readl(rsb->regs + RSB_INTS);
rsb->status = status;
- /* Clear interrupts */
+ /* Disable and clear interrupts */
+ writel(0, rsb->regs + RSB_CTRL);
status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR |
RSB_INTS_TRANS_OVER);
writel(status, rsb->regs + RSB_INTS);
@@ -640,6 +639,13 @@ static int sunxi_rsb_init_controller(str
writel(RSB_CCR_SDA_OUT_DELAY(clk_delay) | RSB_CCR_CLK_DIV(clk_div - 1),
rsb->regs + RSB_CCR);
+ /*
+ * Select the interrupts we care about. They will not actually fire
+ * until the RSB_CTRL_GLOBAL_INT_ENB bit is set.
+ */
+ writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+ rsb->regs + RSB_INTE);
+
return 0;
err_clk_disable:

View File

@ -1,8 +1,7 @@
From 2f76dd45fb1faf046aaaaddb6021312622002a3d Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 10 Jan 2021 00:51:31 -0600
Subject: [PATCH 4/4] media: sunxi-cir: Implement suspend/resume/shutdown
callbacks
Subject: [PATCH] media: sunxi-cir: Implement suspend/resume/shutdown callbacks
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

View File

@ -1,60 +1,55 @@
From ca108f8037f884821d5b70ea0f4cfd73a9ae4188 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 25 Aug 2019 05:35:08 -0500
Subject: [PATCH 16/31] irqchip/sun6i-r: Use a stacked irqchip driver
Subject: [PATCH] irqchip/sun6i-r: Use a stacked irqchip driver
The R_INTC in the A31 and newer sun8i/sun50i SoCs is more similar to the
original sun4i interrupt controller than the sun7i/sun9i NMI controller.
It is used for two distinct purposes:
1) To control the trigger, latch, and mask for the NMI input pin
2) To provide the interrupt input for the ARISC coprocessor
- To control the trigger, latch, and mask for the NMI input pin
- To provide the interrupt input for the ARISC coprocessor
As this interrupt controller is not documented, information about it
comes from vendor-provided ARISC firmware and from experimentation.
Like the original sun4i interrupt controller, it has:
- A VECTOR_REG at 0x00 (configurable via the BASE_ADDR_REG at 0x04)
- A NMI_CTRL_REG, PENDING_REG, and ENABLE_REG as used by both the
sun4i and sunxi-nmi drivers
- A MASK_REG at 0x50
- A RESP_REG at 0x60
comes from vendor-provided firmware blobs and from experimentation.
Differences from the sun4i interrupt controller appear to be:
- It is only known to have one register of each kind (max 32 inputs)
- It only has one or two registers of each kind (max 32 or 64 IRQs)
- Multiplexing logic is added to support additional inputs
- There is no FIQ-related logic
- There is no interrupt priority logic
In order to fulfill its two purposes, this hardware block combines two
In order to fulfill its two purposes, this hardware block combines four
types of IRQs. First, the NMI pin is routed to the "IRQ 0" input on this
chip, with a trigger type controlled by the NMI_CTRL_REG. The "IRQ 0
pending" output from this chip, if enabled, is then routed to a SPI IRQ
input on the GIC, as IRQ_TYPE_LEVEL_HIGH. In other words, bit 0 of
ENABLE_REG *does* affect the NMI IRQ seen at the GIC.
input on the GIC. In other words, bit 0 of IRQ_ENABLE_REG *does* affect
the NMI IRQ seen at the GIC.
The NMI is then followed by a contiguous block of (at least) 15 IRQ
inputs that are connected in parallel to both R_INTC and the GIC. Or
in other words, the other bits of ENABLE_REG *do not* affect the IRQs
seen at the GIC.
The NMI is followed by a contiguous block of 15 "direct" (my name for
them) IRQ inputs that are connected in parallel to both R_INTC and the
GIC. Or in other words, these bits of IRQ_ENABLE_REG *do not* affect the
IRQs seen at the GIC.
Finally, the global "IRQ pending" output from R_INTC, after being masked
by MASK_REG and RESP_REG, is connected to the "external interrupt" input
of the ARISC CPU (an OR1200). This path is not relevant to Linux.
Following the direct IRQs are the ARISC's copy of banked IRQs for shared
peripherals. These are not relevant to Linux. The remaining IRQs are
connected to a multiplexer and provide access to the first (up to) 128
SPIs from the ARISC. This range of SPIs overlaps with the direct IRQs.
Because of the 1:1 correspondence between R_INTC and GIC inputs, this is
a perfect scenario for using a stacked irqchip driver. We want to hook
into enabling/disabling IRQs to add more features to the GIC
(specifically to allow masking the NMI and setting its trigger type),
but we don't need to actually handle the IRQ in this driver.
into setting the NMI trigger type, but not actually handle any IRQ here.
And since R_INTC is in the always-on power domain, and its output is
connected directly in to the power management coprocessor, a stacked
irqchip driver provides a simple way to add wakeup support to this set
of IRQs. That is a future patch; for now, just the NMI is moved over.
To allow access to all multiplexed IRQs, this driver requires a new
binding where the interrupt number matches the GIC interrupt number.
(This moves the NMI from number 0 to 32 or 96, depending on the SoC.)
For simplicity, copy the three-cell GIC binding; this disambiguates
interrupt 0 in the old binding (the NMI) from interrupt 0 in the new
binding (SPI 0) by the number of cells.
This driver keeps the same DT binding as the existing driver. The
"interrupt" property of the R_INTC node is used to determine 1) the
offset between GIC and R_INTC hwirq numbers and 2) the type of trigger
between the R_INTC "IRQ 0 pending" output and the GIC NMI input.
Since R_INTC is in the always-on power domain, and its output is visible
to the power management coprocessor, a stacked irqchip driver provides a
simple way to add wakeup support to any of its IRQs. That is the next
patch; for now, just the NMI is moved over.
This commit mostly reverts commit 173bda53b340 ("irqchip/sunxi-nmi:
Support sun6i-a31-r-intc compatible").
@ -64,9 +59,9 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
arch/arm/mach-sunxi/Kconfig | 2 +
arch/arm64/Kconfig.platforms | 2 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-sun6i-r.c | 212 ++++++++++++++++++++++++++++++++
drivers/irqchip/irq-sunxi-nmi.c | 26 +---
5 files changed, 220 insertions(+), 23 deletions(-)
drivers/irqchip/irq-sun6i-r.c | 284 ++++++++++++++++++++++++++++++++
drivers/irqchip/irq-sunxi-nmi.c | 26 +--
5 files changed, 292 insertions(+), 23 deletions(-)
create mode 100644 drivers/irqchip/irq-sun6i-r.c
--- a/arch/arm/mach-sunxi/Kconfig
@ -103,12 +98,49 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o
--- /dev/null
+++ b/drivers/irqchip/irq-sun6i-r.c
@@ -0,0 +1,212 @@
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Allwinner A31 and newer SoCs R_INTC driver
+//
+/*
+ * The R_INTC in Allwinner A31 and newer SoCs manages several types of
+ * interrupts, as shown below:
+ *
+ * NMI IRQ DIRECT IRQs MUXED IRQs
+ * bit 0 bits 1-15^ bits 19-31
+ *
+ * +---------+ +---------+ +---------+ +---------+
+ * | NMI Pad | | IRQ d | | IRQ m | | IRQ m+7 |
+ * +---------+ +---------+ +---------+ +---------+
+ * | | | | | | |
+ * | | | | |......| |
+ * +------V------+ +------------+ | | | +--V------V--+ |
+ * | Invert/ | | Write 1 to | | | | | AND with | |
+ * | Edge Detect | | PENDING[0] | | | | | MUX[m/8] | |
+ * +-------------+ +------------+ | | | +------------+ |
+ * | | | | | | |
+ * +--V-------V--+ +--V--+ | +--V--+ | +--V--+
+ * | Set Reset| | GIC | | | GIC | | | GIC |
+ * | Latch | | SPI | | | SPI |... | ...| SPI |
+ * +-------------+ | N+d | | | m | | | m+7 |
+ * | | +-----+ | +-----+ | +-----+
+ * | | | |
+ * +-------V-+ +-V----------+ +---------V--+ +--------V--------+
+ * | GIC SPI | | AND with | | AND with | | AND with |
+ * | N (=32) | | ENABLE[0] | | ENABLE[d] | | ENABLE[19+m/8] |
+ * +---------+ +------------+ +------------+ +-----------------+
+ * | | |
+ * +------V-----+ +------V-----+ +--------V--------+
+ * | Read | | Read | | Read |
+ * | PENDING[0] | | PENDING[d] | | PENDING[19+m/8] |
+ * +------------+ +------------+ +-----------------+
+ *
+ * ^ bits 16-18 are direct IRQs for peripherals with banked interrupts, such as
+ * the MSGBOX. These IRQs do not map to any GIC SPI.
+ *
+ * The H6 variant adds two more (banked) direct IRQs and implements the full
+ * set of 128 mux bits. This requires a second set of top-level registers.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
@ -118,123 +150,138 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#define NMI_HWIRQ 0
+#define NMI_HWIRQ_BIT BIT(NMI_HWIRQ)
+#define SUN6I_NMI_CTRL (0x0c)
+#define SUN6I_IRQ_PENDING(n) (0x10 + 4 * (n))
+#define SUN6I_IRQ_ENABLE(n) (0x40 + 4 * (n))
+#define SUN6I_MUX_ENABLE(n) (0xc0 + 4 * (n))
+
+#define SUN6I_R_INTC_NR_IRQS 16
+#define SUN6I_NMI_SRC_TYPE_LEVEL_LOW 0
+#define SUN6I_NMI_SRC_TYPE_EDGE_FALLING 1
+#define SUN6I_NMI_SRC_TYPE_LEVEL_HIGH 2
+#define SUN6I_NMI_SRC_TYPE_EDGE_RISING 3
+
+#define SUN6I_R_INTC_NMI_CTRL 0x0c
+#define SUN6I_R_INTC_PENDING 0x10
+#define SUN6I_R_INTC_ENABLE 0x40
+#define SUN6I_NMI_BIT BIT(0)
+
+#define SUN6I_NMI_NEEDS_ACK ((void *)1)
+
+#define SUN6I_NR_TOP_LEVEL_IRQS 64
+#define SUN6I_NR_DIRECT_IRQS 16
+#define SUN6I_NR_MUX_BITS 128
+
+static void __iomem *base;
+static irq_hw_number_t parent_offset;
+static u32 parent_type;
+static irq_hw_number_t nmi_hwirq;
+
+static struct irq_chip sun6i_r_intc_edge_chip;
+static struct irq_chip sun6i_r_intc_level_chip;
+
+static void sun6i_r_intc_nmi_ack(void)
+static void sun6i_r_intc_ack_nmi(void)
+{
+ /*
+ * The NMI IRQ channel has a latch, separate from its trigger.
+ * This latch must be cleared to clear the output to the GIC.
+ */
+ writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_PENDING);
+ writel(SUN6I_NMI_BIT, base + SUN6I_IRQ_PENDING(0));
+}
+
+static void sun6i_r_intc_irq_mask(struct irq_data *data)
+static void sun6i_r_intc_nmi_ack(struct irq_data *data)
+{
+ if (data->hwirq == NMI_HWIRQ)
+ sun6i_r_intc_nmi_ack();
+
+ irq_chip_mask_parent(data);
+ if (irqd_get_trigger_type(data) & IRQ_TYPE_EDGE_BOTH)
+ sun6i_r_intc_ack_nmi();
+ else
+ data->chip_data = SUN6I_NMI_NEEDS_ACK;
+}
+
+static void sun6i_r_intc_irq_unmask(struct irq_data *data)
+static void sun6i_r_intc_nmi_eoi(struct irq_data *data)
+{
+ if (data->hwirq == NMI_HWIRQ)
+ sun6i_r_intc_nmi_ack();
+ /* For oneshot IRQs, delay the ack until the IRQ is unmasked. */
+ if (data->chip_data == SUN6I_NMI_NEEDS_ACK && !irqd_irq_masked(data)) {
+ sun6i_r_intc_ack_nmi();
+ data->chip_data = 0;
+ }
+
+ irq_chip_eoi_parent(data);
+}
+
+static void sun6i_r_intc_nmi_unmask(struct irq_data *data)
+{
+ if (data->chip_data == SUN6I_NMI_NEEDS_ACK) {
+ sun6i_r_intc_ack_nmi();
+ data->chip_data = 0;
+ }
+
+ irq_chip_unmask_parent(data);
+}
+
+static int sun6i_r_intc_irq_set_type(struct irq_data *data, unsigned int type)
+static int sun6i_r_intc_nmi_set_type(struct irq_data *data, unsigned int type)
+{
+ /*
+ * Only the NMI IRQ is routed through this interrupt controller on its
+ * way to the GIC. Other IRQs are routed to the GIC in parallel and
+ * must have a trigger type appropriate for the GIC.
+ *
+ * The "External NMI" input to the GIC actually comes from bit 0 of
+ * this device's PENDING register. So the IRQ type of the NMI, as seen
+ * by the GIC, does not depend on the IRQ type of the NMI pin itself.
+ */
+ if (data->hwirq == NMI_HWIRQ) {
+ struct irq_chip *chip;
+ u32 nmi_src_type;
+ u32 nmi_src_type;
+
+ switch (type) {
+ case IRQ_TYPE_LEVEL_LOW:
+ chip = &sun6i_r_intc_level_chip;
+ nmi_src_type = 0;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ chip = &sun6i_r_intc_edge_chip;
+ nmi_src_type = 1;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ chip = &sun6i_r_intc_level_chip;
+ nmi_src_type = 2;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ chip = &sun6i_r_intc_edge_chip;
+ nmi_src_type = 3;
+ break;
+ default:
+ pr_err("%pOF: invalid trigger type %d for IRQ %d\n",
+ irq_domain_get_of_node(data->domain), type,
+ data->irq);
+ return -EBADR;
+ }
+
+ irq_set_chip_handler_name_locked(data, chip,
+ handle_fasteoi_irq, NULL);
+
+ writel_relaxed(nmi_src_type, base + SUN6I_R_INTC_NMI_CTRL);
+
+ /* Send the R_INTC -> GIC trigger type to the GIC driver. */
+ type = parent_type;
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_EDGE_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_EDGE_FALLING;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ nmi_src_type = SUN6I_NMI_SRC_TYPE_LEVEL_LOW;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return irq_chip_set_type_parent(data, type);
+ writel_relaxed(nmi_src_type, base + SUN6I_NMI_CTRL);
+
+ /*
+ * The "External NMI" GIC input connects to a latch inside R_INTC, not
+ * directly to the pin. So the GIC trigger type does not depend on the
+ * NMI pin trigger type.
+ */
+ return irq_chip_set_type_parent(data, IRQ_TYPE_LEVEL_HIGH);
+}
+
+static struct irq_chip sun6i_r_intc_edge_chip = {
+static int sun6i_r_intc_nmi_set_irqchip_state(struct irq_data *data,
+ enum irqchip_irq_state which,
+ bool state)
+{
+ if (which == IRQCHIP_STATE_PENDING && !state)
+ sun6i_r_intc_ack_nmi();
+
+ return irq_chip_set_parent_state(data, which, state);
+}
+
+static struct irq_chip sun6i_r_intc_nmi_chip = {
+ .name = "sun6i-r-intc",
+ .irq_mask = sun6i_r_intc_irq_mask,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_ack = sun6i_r_intc_nmi_ack,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = sun6i_r_intc_nmi_unmask,
+ .irq_eoi = sun6i_r_intc_nmi_eoi,
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+ .irq_set_type = sun6i_r_intc_irq_set_type,
+ .irq_get_irqchip_state = irq_chip_get_parent_state,
+ .irq_set_irqchip_state = irq_chip_set_parent_state,
+ .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+ .irq_set_type = sun6i_r_intc_nmi_set_type,
+ .irq_set_irqchip_state = sun6i_r_intc_nmi_set_irqchip_state,
+ .flags = IRQCHIP_SET_TYPE_MASKED |
+ IRQCHIP_SKIP_SET_WAKE,
+};
+
+static struct irq_chip sun6i_r_intc_level_chip = {
+ .name = "sun6i-r-intc",
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = sun6i_r_intc_irq_unmask,
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+ .irq_set_type = sun6i_r_intc_irq_set_type,
+ .irq_get_irqchip_state = irq_chip_get_parent_state,
+ .irq_set_irqchip_state = irq_chip_set_parent_state,
+ .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+static int sun6i_r_intc_domain_translate(struct irq_domain *domain,
+ struct irq_fwspec *fwspec,
+ unsigned long *hwirq,
+ unsigned int *type)
+{
+ /* Accept the old two-cell binding for the NMI only. */
+ if (fwspec->param_count == 2 && fwspec->param[0] == 0) {
+ *hwirq = nmi_hwirq;
+ *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+ return 0;
+ }
+
+ /* Otherwise this binding should match the GIC SPI binding. */
+ if (fwspec->param_count < 3)
+ return -EINVAL;
+ if (fwspec->param[0] != GIC_SPI)
+ return -EINVAL;
+
+ *hwirq = fwspec->param[1];
+ *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
+
+ return 0;
+}
+
+static int sun6i_r_intc_domain_alloc(struct irq_domain *domain,
+ unsigned int virq,
@ -242,51 +289,73 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+{
+ struct irq_fwspec *fwspec = arg;
+ struct irq_fwspec gic_fwspec;
+ irq_hw_number_t hwirq;
+ unsigned long hwirq;
+ unsigned int type;
+ int i, ret;
+
+ ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type);
+ ret = sun6i_r_intc_domain_translate(domain, fwspec, &hwirq, &type);
+ if (ret)
+ return ret;
+ if (hwirq + nr_irqs > SUN6I_R_INTC_NR_IRQS)
+ if (hwirq + nr_irqs > SUN6I_NR_MUX_BITS)
+ return -EINVAL;
+
+ /* Construct a GIC-compatible fwspec from this fwspec. */
+ gic_fwspec = (struct irq_fwspec) {
+ .fwnode = domain->parent->fwnode,
+ .param_count = 3,
+ .param = { GIC_SPI, parent_offset + hwirq, type },
+ .param = { GIC_SPI, hwirq, type },
+ };
+
+ for (i = 0; i < nr_irqs; ++i)
+ irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
+ &sun6i_r_intc_level_chip, NULL);
+ ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_fwspec);
+ if (ret)
+ return ret;
+
+ return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_fwspec);
+ for (i = 0; i < nr_irqs; ++i, ++hwirq, ++virq) {
+ if (hwirq == nmi_hwirq) {
+ irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
+ &sun6i_r_intc_nmi_chip, 0);
+ irq_set_handler(virq, handle_fasteoi_ack_irq);
+ } else {
+ /* Only the NMI is currently supported. */
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static const struct irq_domain_ops sun6i_r_intc_domain_ops = {
+ .translate = irq_domain_translate_twocell,
+ .translate = sun6i_r_intc_domain_translate,
+ .alloc = sun6i_r_intc_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+};
+
+static void sun6i_r_intc_resume(void)
+{
+ int i;
+
+ /* Only the NMI is relevant during normal operation. */
+ writel_relaxed(SUN6I_NMI_BIT, base + SUN6I_IRQ_ENABLE(0));
+ for (i = 1; i < BITS_TO_U32(SUN6I_NR_TOP_LEVEL_IRQS); ++i)
+ writel_relaxed(0, base + SUN6I_IRQ_ENABLE(i));
+}
+
+static int __init sun6i_r_intc_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_domain *domain, *parent_domain;
+ struct of_phandle_args parent_irq;
+ struct of_phandle_args nmi_parent;
+ int ret;
+
+ /* Extract the R_INTC -> GIC mapping from the OF node. */
+ ret = of_irq_parse_one(node, 0, &parent_irq);
+ /* Extract the NMI hwirq number from the OF node. */
+ ret = of_irq_parse_one(node, 0, &nmi_parent);
+ if (ret)
+ return ret;
+ if (parent_irq.args_count != 3 || parent_irq.args[0] != GIC_SPI)
+ if (nmi_parent.args_count < 3 ||
+ nmi_parent.args[0] != GIC_SPI ||
+ nmi_parent.args[2] != IRQ_TYPE_LEVEL_HIGH)
+ return -EINVAL;
+ parent_offset = parent_irq.args[1];
+ parent_type = parent_irq.args[2];
+ nmi_hwirq = nmi_parent.args[1];
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
@ -300,8 +369,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ return PTR_ERR(base);
+ }
+
+ domain = irq_domain_add_hierarchy(parent_domain, 0,
+ SUN6I_R_INTC_NR_IRQS, node,
+ domain = irq_domain_add_hierarchy(parent_domain, 0, 0, node,
+ &sun6i_r_intc_domain_ops, NULL);
+ if (!domain) {
+ pr_err("%pOF: Failed to allocate domain\n", node);
@ -309,9 +377,8 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ return -ENOMEM;
+ }
+
+ /* Clear and enable the NMI. */
+ writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_PENDING);
+ writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_ENABLE);
+ sun6i_r_intc_ack_nmi();
+ sun6i_r_intc_resume();
+
+ return 0;
+}

View File

@ -1,11 +1,11 @@
From c1f31a42b5d9be0000b1748e0c4bdaf22060abfc Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 12 Jan 2020 20:00:36 -0600
Subject: [PATCH 17/31] irqchip/sun6i-r: Add wakeup support
Subject: [PATCH] irqchip/sun6i-r: Add wakeup support
Maintain a mask of wake-enabled IRQs, and enable them in hardware
during the syscore phase of suspend. The restore the original mask
of enabled IRQs (just the NMI) during resume.
Maintain bitmaps of wake-enabled IRQs and mux inputs, and program them
to the hardware during the syscore phase of suspend and shutdown. Then
restore the original set of enabled IRQs (only the NMI) during resume.
This serves two purposes. First, it lets power management firmware
running on the ARISC coprocessor know which wakeup sources Linux wants
@ -14,21 +14,27 @@ down the remainder of the clock tree. Second, it preconfigures the
coprocessor's interrupt controller, so the firmware's wakeup logic
is as simple as waiting for an interrupt to arrive.
The suspend/resume logic is not conditional on PM_SLEEP because it is
identical to the init/shutdown logic. Wake IRQs may be enabled during
shutdown to allow powering the board back on. As an example, see
commit a5c5e50cce9d ("Input: gpio-keys - add shutdown callback").
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/irqchip/irq-sun6i-r.c | 51 +++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
drivers/irqchip/irq-sun6i-r.c | 107 ++++++++++++++++++++++++++++++++--
1 file changed, 101 insertions(+), 6 deletions(-)
--- a/drivers/irqchip/irq-sun6i-r.c
+++ b/drivers/irqchip/irq-sun6i-r.c
@@ -3,12 +3,14 @@
// Allwinner A31 and newer SoCs R_INTC driver
//
@@ -39,6 +39,7 @@
* set of 128 mux bits. This requires a second set of top-level registers.
*/
+#include <linux/atomic.h>
+#include <linux/bitmap.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
@@ -46,6 +47,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
@ -36,94 +42,169 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -24,6 +26,9 @@
static void __iomem *base;
static irq_hw_number_t parent_offset;
static u32 parent_type;
+#ifdef CONFIG_PM_SLEEP
+static atomic_t wake_mask;
+#endif
@@ -67,8 +69,17 @@
#define SUN6I_NR_DIRECT_IRQS 16
#define SUN6I_NR_MUX_BITS 128
static struct irq_chip sun6i_r_intc_edge_chip;
static struct irq_chip sun6i_r_intc_level_chip;
@@ -104,6 +109,20 @@ static int sun6i_r_intc_irq_set_type(str
return irq_chip_set_type_parent(data, type);
+struct sun6i_r_intc_variant {
+ u32 first_mux_irq;
+ u32 nr_mux_irqs;
+ u32 mux_valid[BITS_TO_U32(SUN6I_NR_MUX_BITS)];
+};
+
static void __iomem *base;
static irq_hw_number_t nmi_hwirq;
+static DECLARE_BITMAP(wake_irq_enabled, SUN6I_NR_TOP_LEVEL_IRQS);
+static DECLARE_BITMAP(wake_mux_enabled, SUN6I_NR_MUX_BITS);
+static DECLARE_BITMAP(wake_mux_valid, SUN6I_NR_MUX_BITS);
static void sun6i_r_intc_ack_nmi(void)
{
@@ -145,6 +156,21 @@ static int sun6i_r_intc_nmi_set_irqchip_
return irq_chip_set_parent_state(data, which, state);
}
+#ifdef CONFIG_PM_SLEEP
+static int sun6i_r_intc_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+ if (on)
+ atomic_or(BIT(data->hwirq), &wake_mask);
+ unsigned long offset_from_nmi = data->hwirq - nmi_hwirq;
+
+ if (offset_from_nmi < SUN6I_NR_DIRECT_IRQS)
+ assign_bit(offset_from_nmi, wake_irq_enabled, on);
+ else if (test_bit(data->hwirq, wake_mux_valid))
+ assign_bit(data->hwirq, wake_mux_enabled, on);
+ else
+ atomic_andnot(BIT(data->hwirq), &wake_mask);
+ /* Not wakeup capable. */
+ return -EPERM;
+
+ return 0;
+}
+#else
+#define sun6i_r_intc_irq_set_wake NULL
+#endif
+
static struct irq_chip sun6i_r_intc_edge_chip = {
static struct irq_chip sun6i_r_intc_nmi_chip = {
.name = "sun6i-r-intc",
.irq_mask = sun6i_r_intc_irq_mask,
@@ -113,6 +132,7 @@ static struct irq_chip sun6i_r_intc_edge
.irq_set_type = sun6i_r_intc_irq_set_type,
.irq_get_irqchip_state = irq_chip_get_parent_state,
.irq_set_irqchip_state = irq_chip_set_parent_state,
.irq_ack = sun6i_r_intc_nmi_ack,
@@ -154,8 +180,19 @@ static struct irq_chip sun6i_r_intc_nmi_
.irq_set_affinity = irq_chip_set_affinity_parent,
.irq_set_type = sun6i_r_intc_nmi_set_type,
.irq_set_irqchip_state = sun6i_r_intc_nmi_set_irqchip_state,
- .flags = IRQCHIP_SET_TYPE_MASKED |
- IRQCHIP_SKIP_SET_WAKE,
+ .irq_set_wake = sun6i_r_intc_irq_set_wake,
.irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent,
.flags = IRQCHIP_SET_TYPE_MASKED,
};
@@ -126,6 +146,7 @@ static struct irq_chip sun6i_r_intc_leve
.irq_set_type = sun6i_r_intc_irq_set_type,
.irq_get_irqchip_state = irq_chip_get_parent_state,
.irq_set_irqchip_state = irq_chip_set_parent_state,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static struct irq_chip sun6i_r_intc_wakeup_chip = {
+ .name = "sun6i-r-intc",
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_eoi = irq_chip_eoi_parent,
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+ .irq_set_type = irq_chip_set_type_parent,
+ .irq_set_wake = sun6i_r_intc_irq_set_wake,
.irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent,
.flags = IRQCHIP_SET_TYPE_MASKED,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
};
@@ -166,6 +187,34 @@ static const struct irq_domain_ops sun6i
static int sun6i_r_intc_domain_translate(struct irq_domain *domain,
@@ -215,8 +252,8 @@ static int sun6i_r_intc_domain_alloc(str
&sun6i_r_intc_nmi_chip, 0);
irq_set_handler(virq, handle_fasteoi_ack_irq);
} else {
- /* Only the NMI is currently supported. */
- return -EINVAL;
+ irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
+ &sun6i_r_intc_wakeup_chip, 0);
}
}
@@ -229,6 +266,22 @@ static const struct irq_domain_ops sun6i
.free = irq_domain_free_irqs_common,
};
+#ifdef CONFIG_PM_SLEEP
+static int sun6i_r_intc_suspend(void)
+{
+ /* All wake IRQs are enabled during system sleep. */
+ writel_relaxed(atomic_read(&wake_mask), base + SUN6I_R_INTC_ENABLE);
+ u32 buf[BITS_TO_U32(max(SUN6I_NR_TOP_LEVEL_IRQS, SUN6I_NR_MUX_BITS))];
+ int i;
+
+ /* Wake IRQs are enabled during system sleep and shutdown. */
+ bitmap_to_arr32(buf, wake_irq_enabled, SUN6I_NR_TOP_LEVEL_IRQS);
+ for (i = 0; i < BITS_TO_U32(SUN6I_NR_TOP_LEVEL_IRQS); ++i)
+ writel_relaxed(buf[i], base + SUN6I_IRQ_ENABLE(i));
+ bitmap_to_arr32(buf, wake_mux_enabled, SUN6I_NR_MUX_BITS);
+ for (i = 0; i < BITS_TO_U32(SUN6I_NR_MUX_BITS); ++i)
+ writel_relaxed(buf[i], base + SUN6I_MUX_ENABLE(i));
+
+ return 0;
+}
+
+static void sun6i_r_intc_resume(void)
static void sun6i_r_intc_resume(void)
{
int i;
@@ -239,8 +292,20 @@ static void sun6i_r_intc_resume(void)
writel_relaxed(0, base + SUN6I_IRQ_ENABLE(i));
}
+static void sun6i_r_intc_shutdown(void)
+{
+ /* Only the NMI is relevant during normal operation. */
+ writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_ENABLE);
+ sun6i_r_intc_suspend();
+}
+
+static struct syscore_ops sun6i_r_intc_syscore_ops = {
+ .suspend = sun6i_r_intc_suspend,
+ .resume = sun6i_r_intc_resume,
+ .shutdown = sun6i_r_intc_shutdown,
+};
+
+static void sun6i_r_intc_syscore_init(void)
+{
+ register_syscore_ops(&sun6i_r_intc_syscore_ops);
+}
+#else
+static inline void sun6i_r_intc_syscore_init(void) {}
+#endif
+
static int __init sun6i_r_intc_init(struct device_node *node,
struct device_node *parent)
- struct device_node *parent)
+ struct device_node *parent,
+ const struct sun6i_r_intc_variant *v)
{
@@ -207,6 +256,8 @@ static int __init sun6i_r_intc_init(stru
writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_PENDING);
writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_ENABLE);
struct irq_domain *domain, *parent_domain;
struct of_phandle_args nmi_parent;
@@ -256,6 +321,9 @@ static int __init sun6i_r_intc_init(stru
return -EINVAL;
nmi_hwirq = nmi_parent.args[1];
+ sun6i_r_intc_syscore_init();
+ bitmap_set(wake_irq_enabled, v->first_mux_irq, v->nr_mux_irqs);
+ bitmap_from_arr32(wake_mux_valid, v->mux_valid, SUN6I_NR_MUX_BITS);
+
parent_domain = irq_find_host(parent);
if (!parent_domain) {
pr_err("%pOF: Failed to obtain parent domain\n", node);
@@ -276,9 +344,36 @@ static int __init sun6i_r_intc_init(stru
return -ENOMEM;
}
+ register_syscore_ops(&sun6i_r_intc_syscore_ops);
+
sun6i_r_intc_ack_nmi();
sun6i_r_intc_resume();
return 0;
}
IRQCHIP_DECLARE(sun6i_r_intc, "allwinner,sun6i-a31-r-intc", sun6i_r_intc_init);
-IRQCHIP_DECLARE(sun6i_r_intc, "allwinner,sun6i-a31-r-intc", sun6i_r_intc_init);
+
+static const struct sun6i_r_intc_variant sun6i_a31_r_intc_variant __initconst = {
+ .first_mux_irq = 19,
+ .nr_mux_irqs = 13,
+ .mux_valid = { 0xffffffff, 0xfff80000, 0xffffffff, 0x0000000f },
+};
+
+static int __init sun6i_a31_r_intc_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return sun6i_r_intc_init(node, parent, &sun6i_a31_r_intc_variant);
+}
+IRQCHIP_DECLARE(sun6i_a31_r_intc, "allwinner,sun6i-a31-r-intc", sun6i_a31_r_intc_init);
+
+static const struct sun6i_r_intc_variant sun50i_h6_r_intc_variant __initconst = {
+ .first_mux_irq = 21,
+ .nr_mux_irqs = 16,
+ .mux_valid = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff },
+};
+
+static int __init sun50i_h6_r_intc_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return sun6i_r_intc_init(node, parent, &sun50i_h6_r_intc_variant);
+}
+IRQCHIP_DECLARE(sun50i_h6_r_intc, "allwinner,sun50i-h6-r-intc", sun50i_h6_r_intc_init);

View File

@ -0,0 +1,194 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 25 Dec 2020 01:48:33 -0600
Subject: [PATCH] ARM: dts: sunxi: Rename nmi_intc to r_intc
The R_INTC block controls more than just the NMI, and it is a different
hardware block than the NMI INTC found in some other Allwinner SoCs, so
the label "nmi_intc" is inaccurate. Name it "r_intc" to match the
compatible and to match the few references in the vendor documentation.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 2 +-
arch/arm/boot/dts/sun6i-a31-m9.dts | 2 +-
arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts | 2 +-
arch/arm/boot/dts/sun6i-a31.dtsi | 2 +-
arch/arm/boot/dts/sun6i-a31s-primo81.dts | 2 +-
arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi | 2 +-
arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts | 2 +-
arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts | 2 +-
arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi | 2 +-
arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +-
arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 2 +-
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 2 +-
arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts | 2 +-
arch/arm/boot/dts/sun8i-r16-parrot.dts | 2 +-
arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
15 files changed, 15 insertions(+), 15 deletions(-)
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -226,7 +226,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en;
};
--- a/arch/arm/boot/dts/sun6i-a31-m9.dts
+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts
@@ -115,7 +115,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
+++ b/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
@@ -115,7 +115,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -1305,7 +1305,7 @@
clock-output-names = "osc32k";
};
- nmi_intc: interrupt-controller@1f00c00 {
+ r_intc: interrupt-controller@1f00c00 {
compatible = "allwinner,sun6i-a31-r-intc";
interrupt-controller;
#interrupt-cells = <2>;
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -159,7 +159,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en;
};
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
@@ -78,7 +78,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
@@ -148,7 +148,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
--- a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
@@ -98,7 +98,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
@@ -79,7 +79,7 @@
axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
drivevbus-supply = <&reg_vcc5v0>;
x-powers,drive-vbus-en;
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -716,7 +716,7 @@
#clock-cells = <1>;
};
- nmi_intc: interrupt-controller@1f00c00 {
+ r_intc: interrupt-controller@1f00c00 {
compatible = "allwinner,sun6i-a31-r-intc";
interrupt-controller;
#interrupt-cells = <2>;
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
@@ -98,7 +98,7 @@
axp22x: pmic@3a3 {
compatible = "x-powers,axp223";
reg = <0x3a3>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -164,7 +164,7 @@
axp22x: pmic@3a3 {
compatible = "x-powers,axp223";
reg = <0x3a3>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
};
--- a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
+++ b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
@@ -163,7 +163,7 @@
axp22x: pmic@3a3 {
compatible = "x-powers,axp223";
reg = <0x3a3>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
@@ -164,7 +164,7 @@
axp22x: pmic@3a3 {
compatible = "x-powers,axp223";
reg = <0x3a3>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
drivevbus-supply = <&reg_vcc5v0>;
x-powers,drive-vbus-en;
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -92,7 +92,7 @@
axp22x: pmic@3a3 {
compatible = "x-powers,axp223";
reg = <0x3a3>;
- interrupt-parent = <&nmi_intc>;
+ interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
drivevbus-supply = <&reg_vcc5v0>;

View File

@ -1,48 +0,0 @@
From 3d11a3e09d7ff58981243371c52c905b2bb24cde Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 12 Jan 2020 20:21:45 -0600
Subject: [PATCH 18/31] dt-bindings: irq: Add a compatible for the H3 R_INTC
The Allwinner H3 SoC contains an R_INTC that is, as far as we know,
compatible with the R_INTC present in other sun8i/sun50i SoCs starting
with the A31. Since the R_INTC hardware is undocumented, introduce a new
compatible for the R_INTC variant in this SoC, in case there turns out
to be some difference.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
.../allwinner,sun7i-a20-sc-nmi.yaml | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
--- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
@@ -23,22 +23,20 @@ properties:
compatible:
oneOf:
- const: allwinner,sun6i-a31-r-intc
+ - items:
+ - enum:
+ - allwinner,sun8i-a83t-r-intc
+ - allwinner,sun8i-h3-r-intc
+ - allwinner,sun50i-a64-r-intc
+ - allwinner,sun50i-h6-r-intc
+ - const: allwinner,sun6i-a31-r-intc
- const: allwinner,sun6i-a31-sc-nmi
deprecated: true
- const: allwinner,sun7i-a20-sc-nmi
- - items:
- - const: allwinner,sun8i-a83t-r-intc
- - const: allwinner,sun6i-a31-r-intc
- const: allwinner,sun9i-a80-nmi
- items:
- - const: allwinner,sun50i-a64-r-intc
- - const: allwinner,sun6i-a31-r-intc
- - items:
- const: allwinner,sun50i-a100-nmi
- const: allwinner,sun9i-a80-nmi
- - items:
- - const: allwinner,sun50i-h6-r-intc
- - const: allwinner,sun6i-a31-r-intc
reg:
maxItems: 1

View File

@ -0,0 +1,291 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 25 Dec 2020 01:49:51 -0600
Subject: [PATCH] ARM: dts: sunxi: Use the new r_intc binding
The binding of R_INTC was updated to allow specifying interrupts other
than the external NMI, since routing those interrupts through the R_INTC
driver allows using them for wakeup.
Update the device trees to use the new binding.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 2 +-
arch/arm/boot/dts/sun6i-a31-m9.dts | 2 +-
arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts | 2 +-
arch/arm/boot/dts/sun6i-a31.dtsi | 2 +-
arch/arm/boot/dts/sun6i-a31s-primo81.dts | 2 +-
arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi | 2 +-
arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts | 2 +-
arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts | 2 +-
arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi | 2 +-
arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +-
arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 2 +-
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 2 +-
arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts | 4 ++--
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts | 4 ++--
arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts | 4 ++--
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++--
arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +-
arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts | 2 +-
arch/arm/boot/dts/sun8i-r16-parrot.dts | 2 +-
arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
20 files changed, 24 insertions(+), 24 deletions(-)
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -227,7 +227,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en;
};
};
--- a/arch/arm/boot/dts/sun6i-a31-m9.dts
+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts
@@ -116,7 +116,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
+++ b/arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
@@ -116,7 +116,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -1308,7 +1308,7 @@
r_intc: interrupt-controller@1f00c00 {
compatible = "allwinner,sun6i-a31-r-intc";
interrupt-controller;
- #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
reg = <0x01f00c00 0x400>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -160,7 +160,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en;
};
};
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
@@ -79,7 +79,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
@@ -149,7 +149,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
};
--- a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
@@ -99,7 +99,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun6i-reference-design-tablet.dtsi
@@ -80,7 +80,7 @@
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
drivevbus-supply = <&reg_vcc5v0>;
x-powers,drive-vbus-en;
};
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -719,7 +719,7 @@
r_intc: interrupt-controller@1f00c00 {
compatible = "allwinner,sun6i-a31-r-intc";
interrupt-controller;
- #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
reg = <0x01f00c00 0x400>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
@@ -99,7 +99,7 @@
compatible = "x-powers,axp223";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
};
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -165,7 +165,7 @@
compatible = "x-powers,axp223";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
};
};
--- a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
@@ -122,7 +122,7 @@
compatible = "x-powers,axp818", "x-powers,axp813";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
swin-supply = <&reg_dcdc1>;
};
@@ -142,7 +142,7 @@
ac100_rtc: rtc {
compatible = "x-powers,ac100-rtc";
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
clocks = <&ac100_codec>;
#clock-cells = <1>;
clock-output-names = "cko1_rtc",
--- a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
@@ -203,7 +203,7 @@
compatible = "x-powers,axp813";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
fldoin-supply = <&reg_dcdc5>;
swin-supply = <&reg_dcdc1>;
@@ -225,7 +225,7 @@
ac100_rtc: rtc {
compatible = "x-powers,ac100-rtc";
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
clocks = <&ac100_codec>;
#clock-cells = <1>;
clock-output-names = "cko1_rtc",
--- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
@@ -239,7 +239,7 @@
compatible = "x-powers,axp818", "x-powers,axp813";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
swin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
@@ -260,7 +260,7 @@
ac100_rtc: rtc {
compatible = "x-powers,ac100-rtc";
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
clocks = <&ac100_codec>;
#clock-cells = <1>;
clock-output-names = "cko1_rtc",
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
@@ -263,7 +263,7 @@
compatible = "x-powers,axp813";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
swin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
};
@@ -283,7 +283,7 @@
ac100_rtc: rtc {
compatible = "x-powers,ac100-rtc";
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
clocks = <&ac100_codec>;
#clock-cells = <1>;
clock-output-names = "cko1_rtc",
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -1114,7 +1114,7 @@
compatible = "allwinner,sun8i-a83t-r-intc",
"allwinner,sun6i-a31-r-intc";
interrupt-controller;
- #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
reg = <0x01f00c00 0x400>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
--- a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
+++ b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts
@@ -164,7 +164,7 @@
compatible = "x-powers,axp223";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
x-powers,drive-vbus-en;
};
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
@@ -165,7 +165,7 @@
compatible = "x-powers,axp223";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
drivevbus-supply = <&reg_vcc5v0>;
x-powers,drive-vbus-en;
};
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -93,7 +93,7 @@
compatible = "x-powers,axp223";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
eldoin-supply = <&reg_dcdc1>;
drivevbus-supply = <&reg_vcc5v0>;
x-powers,drive-vbus-en;

View File

@ -1,7 +1,7 @@
From acb925d41cbefdf633dd7b1a75179aef7dd2c131 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 12 Jan 2020 20:27:08 -0600
Subject: [PATCH 19/31] ARM: dts: sunxi: h3/h5: Add r_intc node
Subject: [PATCH] ARM: dts: sunxi: h3/h5: Add r_intc node
The H3 and H5 SoCs have an additional interrupt controller in the RTC
power domain that can be used to enable wakeup for certain IRQs.
@ -15,7 +15,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -878,6 +878,15 @@
@@ -877,6 +877,15 @@
#clock-cells = <1>;
};
@ -23,7 +23,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ compatible = "allwinner,sun8i-h3-r-intc",
+ "allwinner,sun6i-a31-r-intc";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
+ reg = <0x01f00c00 0x400>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ };

View File

@ -1,51 +0,0 @@
From 8882b2c4cca1e25bd6b6fb29c9ea072d8ef7f68f Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 25 Aug 2019 19:41:02 -0500
Subject: [PATCH 20/31] ARM: dts: sunxi: h3/h5: Move wakeup-capable IRQs to
r_intc
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.
For the H3/H5, r_intc IRQ numbers are offset by 32 from the GIC IRQ
numbers.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -871,8 +871,9 @@
rtc: rtc@1f00000 {
/* compatible is in per SoC .dtsi file */
reg = <0x01f00000 0x400>;
- interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>,
+ <9 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
clocks = <&osc32k>;
#clock-cells = <1>;
@@ -908,7 +909,8 @@
clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
clock-names = "apb", "ir";
resets = <&r_ccu RST_APB0_IR>;
- interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x400>;
status = "disabled";
};
@@ -929,7 +931,8 @@
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
- interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&rtc 0>;
clock-names = "apb", "hosc", "losc";
gpio-controller;

View File

@ -0,0 +1,139 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 25 Dec 2020 02:05:58 -0600
Subject: [PATCH] ARM: dts: sunxi: Move wakeup-capable IRQs to r_intc
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.
In addition to the external NMI input, which is already routed through
r_intc, these include PIO and R_PIO (gpio-keys), the LRADC, and the RTC.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/boot/dts/sun6i-a31.dtsi | 4 ++++
arch/arm/boot/dts/sun8i-a23-a33.dtsi | 4 ++++
arch/arm/boot/dts/sun8i-a83t.dtsi | 3 +++
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 3 +++
4 files changed, 14 insertions(+)
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -611,6 +611,7 @@
pio: pinctrl@1c20800 {
compatible = "allwinner,sun6i-a31-pinctrl";
reg = <0x01c20800 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
@@ -802,6 +803,7 @@
lradc: lradc@1c22800 {
compatible = "allwinner,sun4i-a10-lradc-keys";
reg = <0x01c22800 0x100>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -1299,6 +1301,7 @@
#clock-cells = <1>;
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc32k>;
@@ -1383,6 +1386,7 @@
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun6i-a31-r-pinctrl";
reg = <0x01f02c00 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 0>, <&osc24M>, <&rtc 0>;
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -338,6 +338,7 @@
pio: pinctrl@1c20800 {
/* compatible gets set in SoC specific dtsi file */
reg = <0x01c20800 0x400>;
+ interrupt-parent = <&r_intc>;
/* interrupts get set in SoC specific dtsi file */
clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
clock-names = "apb", "hosc", "losc";
@@ -473,6 +474,7 @@
lradc: lradc@1c22800 {
compatible = "allwinner,sun4i-a10-lradc-keys";
reg = <0x01c22800 0x100>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -709,6 +711,7 @@
rtc: rtc@1f00000 {
compatible = "allwinner,sun8i-a23-rtc";
reg = <0x01f00000 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out";
@@ -805,6 +808,7 @@
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun8i-a23-r-pinctrl";
reg = <0x01f02c00 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 0>, <&osc24M>, <&rtc 0>;
clock-names = "apb", "hosc", "losc";
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -708,6 +708,7 @@
pio: pinctrl@1c20800 {
compatible = "allwinner,sun8i-a83t-pinctrl";
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
@@ -1150,6 +1151,7 @@
r_lradc: lradc@1f03c00 {
compatible = "allwinner,sun8i-a83t-r-lradc";
reg = <0x01f03c00 0x100>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -1157,6 +1159,7 @@
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun8i-a83t-r-pinctrl";
reg = <0x01f02c00 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>,
<&osc16Md512>;
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -413,6 +413,7 @@
pio: pinctrl@1c20800 {
/* compatible is in per SoC .dtsi file */
reg = <0x01c20800 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
@@ -870,6 +871,7 @@
rtc: rtc@1f00000 {
/* compatible is in per SoC .dtsi file */
reg = <0x01f00000 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
@@ -927,6 +929,7 @@
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&rtc 0>;
clock-names = "apb", "hosc", "losc";

View File

@ -0,0 +1,232 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 25 Dec 2020 01:56:58 -0600
Subject: [PATCH] arm64: dts: allwinner: Use the new r_intc binding
The binding of R_INTC was updated to allow specifying interrupts other
than the external NMI, since routing those interrupts through the R_INTC
driver allows using them for wakeup.
Update the device trees to use the new binding.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi | 2 +-
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts | 4 ++--
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 5 ++---
17 files changed, 19 insertions(+), 20 deletions(-)
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
@@ -173,7 +173,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -191,7 +191,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
@@ -152,7 +152,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
@@ -185,7 +185,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
@@ -192,7 +192,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -139,7 +139,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
@@ -248,7 +248,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -245,7 +245,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
@@ -266,7 +266,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
x-powers,drive-vbus-en;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
@@ -46,7 +46,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
@@ -205,7 +205,7 @@
compatible = "x-powers,axp803";
reg = <0x3a3>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
wakeup-source;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -1215,7 +1215,7 @@
compatible = "allwinner,sun50i-a64-r-intc",
"allwinner,sun6i-a31-r-intc";
interrupt-controller;
- #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
reg = <0x01f00c00 0x400>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -157,7 +157,7 @@
compatible = "x-powers,axp805", "x-powers,axp806";
reg = <0x36>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
x-powers,self-working-mode;
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
@@ -182,7 +182,7 @@
compatible = "x-powers,axp805", "x-powers,axp806";
reg = <0x36>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
x-powers,self-working-mode;
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
@@ -119,7 +119,7 @@
compatible = "x-powers,axp805", "x-powers,axp806";
reg = <0x36>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
x-powers,self-working-mode;
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
@@ -167,7 +167,7 @@
compatible = "x-powers,axp805", "x-powers,axp806";
reg = <0x36>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
x-powers,self-working-mode;
@@ -280,7 +280,7 @@
compatible = "nxp,pcf8563";
reg = <0x51>;
interrupt-parent = <&r_intc>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
#clock-cells = <0>;
};
};
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -931,10 +931,9 @@
};
r_intc: interrupt-controller@7021000 {
- compatible = "allwinner,sun50i-h6-r-intc",
- "allwinner,sun6i-a31-r-intc";
+ compatible = "allwinner,sun50i-h6-r-intc";
interrupt-controller;
- #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
reg = <0x07021000 0x400>;
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
};

View File

@ -1,51 +0,0 @@
From 79d2176f5cf2902afd677a7fa8b5247e5710c132 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 12 Jan 2020 20:32:15 -0600
Subject: [PATCH 22/31] arm64: dts: allwinner: a64: Move wakeup-capable IRQs to
r_intc
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.
For the A64, r_intc IRQ numbers are offset by 32 from the GIC IRQ
numbers.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -1205,8 +1205,9 @@
compatible = "allwinner,sun50i-a64-rtc",
"allwinner,sun8i-h3-rtc";
reg = <0x01f00000 0x400>;
- interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>,
+ <9 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
clocks = <&osc32k>;
#clock-cells = <1>;
@@ -1257,7 +1258,8 @@
clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
clock-names = "apb", "ir";
resets = <&r_ccu RST_APB0_IR>;
- interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&r_ir_rx_pin>;
status = "disabled";
@@ -1277,7 +1279,8 @@
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun50i-a64-r-pinctrl";
reg = <0x01f02c00 0x400>;
- interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
gpio-controller;

View File

@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 25 Dec 2020 02:05:58 -0600
Subject: [PATCH] arm64: dts: allwinner: Move wakeup-capable IRQs to r_intc
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.
In addition to the external NMI input, which is already routed through
r_intc, these include PIO and R_PIO (gpio-keys), the LRADC, and the RTC.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 4 ++++
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 3 +++
2 files changed, 7 insertions(+)
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -644,6 +644,7 @@
pio: pinctrl@1c20800 {
compatible = "allwinner,sun50i-a64-pinctrl";
reg = <0x01c20800 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
@@ -814,6 +815,7 @@
compatible = "allwinner,sun50i-a64-lradc",
"allwinner,sun8i-a83t-r-lradc";
reg = <0x01c21800 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -1204,6 +1206,7 @@
compatible = "allwinner,sun50i-a64-rtc",
"allwinner,sun8i-h3-rtc";
reg = <0x01f00000 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
@@ -1275,6 +1278,7 @@
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun50i-a64-r-pinctrl";
reg = <0x01f02c00 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -305,6 +305,7 @@
pio: pinctrl@300b000 {
compatible = "allwinner,sun50i-h6-pinctrl";
reg = <0x0300b000 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
@@ -906,6 +907,7 @@
rtc: rtc@7000000 {
compatible = "allwinner,sun50i-h6-rtc";
reg = <0x07000000 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
@@ -941,6 +943,7 @@
r_pio: pinctrl@7022000 {
compatible = "allwinner,sun50i-h6-r-pinctrl";
reg = <0x07022000 0x400>;
+ interrupt-parent = <&r_intc>;
interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>;

View File

@ -1,44 +0,0 @@
From 537cf6daced84919286130c68735a248c62c186d Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 12 Jan 2020 20:33:18 -0600
Subject: [PATCH 23/31] arm64: dts: allwinner: h6: Fix indentation of IR node
This node was indented by two tabs when added instead of one.
Remove the extra tab.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 22 ++++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -965,17 +965,17 @@
};
r_ir: ir@7040000 {
- compatible = "allwinner,sun50i-h6-ir",
- "allwinner,sun6i-a31-ir";
- reg = <0x07040000 0x400>;
- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&r_ccu CLK_R_APB1_IR>,
- <&r_ccu CLK_IR>;
- clock-names = "apb", "ir";
- resets = <&r_ccu RST_R_APB1_IR>;
- pinctrl-names = "default";
- pinctrl-0 = <&r_ir_rx_pin>;
- status = "disabled";
+ compatible = "allwinner,sun50i-h6-ir",
+ "allwinner,sun6i-a31-ir";
+ reg = <0x07040000 0x400>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&r_ccu CLK_R_APB1_IR>,
+ <&r_ccu CLK_IR>;
+ clock-names = "apb", "ir";
+ resets = <&r_ccu RST_R_APB1_IR>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_ir_rx_pin>;
+ status = "disabled";
};
r_i2c: i2c@7081400 {

View File

@ -1,53 +0,0 @@
From d05c22e9079675ba1834ddac322897b45026ff90 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 25 Aug 2019 05:35:23 -0500
Subject: [PATCH 24/31] arm64: dts: allwinner: h6: Move wakeup-capable IRQs to
r_intc
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.
For the H6, r_intc IRQ numbers are offset by 96 from the GIC IRQ
numbers.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -907,8 +907,9 @@
rtc: rtc@7000000 {
compatible = "allwinner,sun50i-h6-rtc";
reg = <0x07000000 0x400>;
- interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH>,
+ <6 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
#clock-cells = <1>;
};
@@ -944,8 +945,9 @@
r_pio: pinctrl@7022000 {
compatible = "allwinner,sun50i-h6-r-pinctrl";
reg = <0x07022000 0x400>;
- interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = < 9 IRQ_TYPE_LEVEL_HIGH>,
+ <15 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
@@ -968,7 +970,8 @@
compatible = "allwinner,sun50i-h6-ir",
"allwinner,sun6i-a31-ir";
reg = <0x07040000 0x400>;
- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_R_APB1_IR>,
<&r_ccu CLK_IR>;
clock-names = "apb", "ir";

View File

@ -1,8 +1,7 @@
From 87f8a2dea1cc62492a6eab63f50323127e508c3a Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 29 Dec 2019 20:23:28 -0600
Subject: [PATCH 02/31] clk: Implement protected-clocks for all OF clock
providers
Subject: [PATCH] clk: Implement protected-clocks for all OF clock providers
This is a generic implementation of the "protected-clocks" property from
the common clock binding. It allows firmware to inform the OS about

View File

@ -1,7 +1,7 @@
From fedd64540faff5a08239c062e03c64fb70d0aa4d Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 12:39:31 -0600
Subject: [PATCH 03/31] Revert "clk: qcom: Support 'protected-clocks' property"
Subject: [PATCH] Revert "clk: qcom: Support 'protected-clocks' property"
Now that protected-clocks is handled in the clk core, this
driver-specific implementation is redundant.

View File

@ -1,78 +0,0 @@
From 882c9a65a1e6bb9bf1ddee8b2512f57b72cb9860 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 25 Aug 2019 05:36:21 -0500
Subject: [PATCH 25/31] rtc: sun6i: Use wake IRQ instead of device PM ops
Since the RTC has a single IRQ, we can use the generic wake IRQ
implementation instead of defining our own device PM ops. This has the
same effect with quite a bit less code.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/rtc/rtc-sun6i.c | 34 ++++++----------------------------
1 file changed, 6 insertions(+), 28 deletions(-)
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -25,6 +25,7 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
#include <linux/rtc.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -639,33 +640,6 @@ static const struct rtc_class_ops sun6i_
.alarm_irq_enable = sun6i_rtc_alarm_irq_enable
};
-#ifdef CONFIG_PM_SLEEP
-/* Enable IRQ wake on suspend, to wake up from RTC. */
-static int sun6i_rtc_suspend(struct device *dev)
-{
- struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
-
- if (device_may_wakeup(dev))
- enable_irq_wake(chip->irq);
-
- return 0;
-}
-
-/* Disable IRQ wake on resume. */
-static int sun6i_rtc_resume(struct device *dev)
-{
- struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
-
- if (device_may_wakeup(dev))
- disable_irq_wake(chip->irq);
-
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(sun6i_rtc_pm_ops,
- sun6i_rtc_suspend, sun6i_rtc_resume);
-
static int sun6i_rtc_probe(struct platform_device *pdev)
{
struct sun6i_rtc_dev *chip = sun6i_rtc;
@@ -716,6 +690,11 @@ static int sun6i_rtc_probe(struct platfo
clk_prepare_enable(chip->losc);
device_init_wakeup(&pdev->dev, 1);
+ ret = dev_pm_set_wake_irq(&pdev->dev, chip->irq);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not set wake IRQ\n");
+ return ret;
+ }
chip->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(chip->rtc))
@@ -756,7 +735,6 @@ static struct platform_driver sun6i_rtc_
.driver = {
.name = "sun6i-rtc",
.of_match_table = sun6i_rtc_dt_ids,
- .pm = &sun6i_rtc_pm_ops,
},
};
builtin_platform_driver(sun6i_rtc_driver);

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 1 Jan 2020 16:03:34 -0600
Subject: [PATCH] [DO NOT MERGE] ARM: dts: sunxi: a83t: Protect SCP clocks
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/boot/dts/sun8i-a83t.dtsi | 2 ++
1 file changed, 2 insertions(+)
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -702,6 +702,7 @@
reg = <0x01c20000 0x400>;
clocks = <&osc24M>, <&osc16Md512>;
clock-names = "hosc", "losc";
+ protected-clocks = <CLK_BUS_MSGBOX>;
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -1126,6 +1127,7 @@
clocks = <&osc24M>, <&osc16Md512>, <&osc16M>,
<&ccu CLK_PLL_PERIPH>;
clock-names = "hosc", "losc", "iosc", "pll-periph";
+ protected-clocks = <CLK_APB0_TWD>;
#clock-cells = <1>;
#reset-cells = <1>;
};

View File

@ -1,28 +0,0 @@
From fe9d1c2c4700b8a8a31ee7d431cd9993b26f8953 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 18 Jul 2020 17:18:23 -0500
Subject: [PATCH 26/31] dt-bindings: sram: Add ARM SCP SRAM compatible
As of commit a90b15e0ad72 ("Documentation: bindings: decouple juno
specific details from generic binding"), the SCPI binding in
Documentation/devicetree/bindings/arm/arm,scpi.txt mandates that SRAM
sections used for SCPI shared memory are compatible with arm,scp-shmem.
However, this compatible is missing from the SRAM binding.
Add the arm,scp-shmem compatible here to match the SCPI binding.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
Documentation/devicetree/bindings/sram/sram.yaml | 1 +
1 file changed, 1 insertion(+)
--- a/Documentation/devicetree/bindings/sram/sram.yaml
+++ b/Documentation/devicetree/bindings/sram/sram.yaml
@@ -76,6 +76,7 @@ patternProperties:
- amlogic,meson8b-smp-sram
- amlogic,meson-gxbb-scp-shmem
- amlogic,meson-axg-scp-shmem
+ - arm,scp-shmem
- renesas,smp-sram
- rockchip,rk3066-smp-sram
- samsung,exynos4210-sysram

View File

@ -1,8 +1,7 @@
From 0cd71d2659136cd9bead16348637d317d4bbfa66 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 1 Jan 2020 16:03:46 -0600
Subject: [PATCH 05/31] [DO NOT MERGE] ARM: dts: sunxi: h3/h5: Protect SCP
clocks
Subject: [PATCH] [DO NOT MERGE] ARM: dts: sunxi: h3/h5: Protect SCP clocks
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
@ -19,7 +18,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -883,6 +884,7 @@
@@ -894,6 +895,7 @@
clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
<&ccu CLK_PLL_PERIPH0>;
clock-names = "hosc", "losc", "iosc", "pll-periph";

View File

@ -1,8 +1,7 @@
From bd91939780869b8c6b48e6eae07733660dceb56b Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 15:10:32 -0600
Subject: [PATCH 06/31] [DO NOT MERGE] arm64: dts: allwinner: a64: Protect SCP
clocks
Subject: [PATCH] [DO NOT MERGE] arm64: dts: allwinner: a64: Protect SCP clocks
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
@ -19,7 +18,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -1226,6 +1227,7 @@
@@ -1229,6 +1230,7 @@
clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
<&ccu CLK_PLL_PERIPH0>;
clock-names = "hosc", "losc", "iosc", "pll-periph";

View File

@ -1,8 +1,7 @@
From 082b5969ad4a2705169c1c1612413ba7c98dc27f Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 1 Jan 2020 16:04:01 -0600
Subject: [PATCH 07/31] [DO NOT MERGE] arm64: dts: allwinner: h6: Protect SCP
clocks
Subject: [PATCH] [DO NOT MERGE] arm64: dts: allwinner: h6: Protect SCP clocks
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
@ -19,7 +18,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -918,6 +919,7 @@
@@ -920,6 +921,7 @@
clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
<&ccu CLK_PLL_PERIPH0>;
clock-names = "hosc", "losc", "iosc", "pll-periph";

View File

@ -1,7 +1,7 @@
From d58ad83eaf72e072d0e0205847ab4332dba24cd0 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 17:12:42 -0600
Subject: [PATCH 11/31] bus: sunxi-rsb: Move OF match table
Subject: [PATCH] bus: sunxi-rsb: Move OF match table
For some reason, this driver's OF match table was placed above the
probe/remove functions, far away from the platform_driver definition.
@ -15,7 +15,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -585,12 +585,6 @@ static int of_rsb_register_devices(struc
@@ -614,12 +614,6 @@ static int of_rsb_register_devices(struc
return 0;
}
@ -28,7 +28,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
static int sunxi_rsb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -717,6 +711,12 @@ static int sunxi_rsb_remove(struct platf
@@ -747,6 +741,12 @@ static int sunxi_rsb_remove(struct platf
return 0;
}

View File

@ -1,25 +1,20 @@
From f8f487fcec9fc8ee7861b99dcf833bd82249ab21 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 22:36:04 -0600
Subject: [PATCH 12/31] bus: sunxi-rsb: Split out controller init/exit
functions
Subject: [PATCH] bus: sunxi-rsb: Split out controller init/exit functions
This separates the resource acquisition from the hardware initialization
phase, so the hardware initialization can be repeated after system
suspend/resume. The same is done for the exit/remove function, except
that there is no resource deallocation phase due to the use of devres.
The call to reset_control_deassert() is replaced with a call to
reset_control_reset() to ensure the hardware is fully reinitialized,
regardless of the state firmware left it in.
The requested RSB clock frequency is stored in `struct sunxi_rsb` so it
will be available when reinitializing the hardware.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/bus/sunxi-rsb.c | 129 +++++++++++++++++++++++-----------------
1 file changed, 73 insertions(+), 56 deletions(-)
drivers/bus/sunxi-rsb.c | 127 ++++++++++++++++++++++------------------
1 file changed, 71 insertions(+), 56 deletions(-)
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@ -31,11 +26,11 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
};
/* bus / slave device related functions */
@@ -585,15 +586,75 @@ static int of_rsb_register_devices(struc
@@ -614,16 +615,74 @@ static int of_rsb_register_devices(struc
return 0;
}
+static int sunxi_rsb_init_controller(struct sunxi_rsb *rsb)
+static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb)
+{
+ struct device *dev = rsb->dev;
+ unsigned long p_clk_freq;
@ -48,7 +43,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ return ret;
+ }
+
+ ret = reset_control_reset(rsb->rstc);
+ ret = reset_control_deassert(rsb->rstc);
+ if (ret) {
+ dev_err(dev, "failed to deassert reset line: %d\n", ret);
+ goto err_clk_disable;
@ -89,18 +84,17 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ return ret;
+}
+
+static int sunxi_rsb_exit_controller(struct sunxi_rsb *rsb)
+static void sunxi_rsb_hw_exit(struct sunxi_rsb *rsb)
+{
+ reset_control_assert(rsb->rstc);
+ clk_disable_unprepare(rsb->clk);
+
+ return 0;
+}
+
static int sunxi_rsb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct resource *r;
struct sunxi_rsb *rsb;
- unsigned long p_clk_freq;
- u32 clk_delay, clk_freq = 3000000;
@ -111,15 +105,15 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
of_property_read_u32(np, "clock-frequency", &clk_freq);
if (clk_freq > RSB_MAX_FREQ) {
@@ -608,6 +669,7 @@ static int sunxi_rsb_probe(struct platfo
@@ -638,6 +697,7 @@ static int sunxi_rsb_probe(struct platfo
return -ENOMEM;
rsb->dev = dev;
+ rsb->clk_freq = clk_freq;
platform_set_drvdata(pdev, rsb);
rsb->regs = devm_platform_ioremap_resource(pdev, 0);
@@ -625,63 +687,27 @@ static int sunxi_rsb_probe(struct platfo
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rsb->regs = devm_ioremap_resource(dev, r);
@@ -655,63 +715,27 @@ static int sunxi_rsb_probe(struct platfo
return ret;
}
@ -182,14 +176,14 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
+ return ret;
}
+ ret = sunxi_rsb_init_controller(rsb);
+ ret = sunxi_rsb_hw_init(rsb);
+ if (ret)
+ return ret;
+
/* initialize all devices on the bus into RSB mode */
ret = sunxi_rsb_init_device_mode(rsb);
if (ret)
@@ -690,14 +716,6 @@ static int sunxi_rsb_probe(struct platfo
@@ -720,14 +744,6 @@ static int sunxi_rsb_probe(struct platfo
of_rsb_register_devices(rsb);
return 0;
@ -204,13 +198,13 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
}
static int sunxi_rsb_remove(struct platform_device *pdev)
@@ -705,8 +723,7 @@ static int sunxi_rsb_remove(struct platf
@@ -735,8 +751,7 @@ static int sunxi_rsb_remove(struct platf
struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
- reset_control_assert(rsb->rstc);
- clk_disable_unprepare(rsb->clk);
+ sunxi_rsb_exit_controller(rsb);
+ sunxi_rsb_hw_exit(rsb);
return 0;
}

View File

@ -1,8 +1,7 @@
From 96302816684155abd59e0dbba7a999c0d269e736 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 30 Dec 2019 22:50:02 -0600
Subject: [PATCH 13/31] bus: sunxi-rsb: Implement global suspend/resume
callbacks
Subject: [PATCH] bus: sunxi-rsb: Implement suspend/resume/shutdown callbacks
Since system firmware is likely to use the RSB bus to communicate with a
PMIC while the system is suspended, we cannot make any assumptions about
@ -14,8 +13,8 @@ wakeup event IRQs coming from the PMIC. Thus it uses NOIRQ callbacks.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/bus/sunxi-rsb.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
drivers/bus/sunxi-rsb.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@ -27,39 +26,56 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
@@ -648,6 +649,24 @@ static int sunxi_rsb_exit_controller(str
return 0;
@@ -675,6 +676,22 @@ static void sunxi_rsb_hw_exit(struct sun
clk_disable_unprepare(rsb->clk);
}
+static int __maybe_unused sunxi_rsb_suspend(struct device *dev)
+{
+ struct sunxi_rsb *rsb = dev_get_drvdata(dev);
+
+ return sunxi_rsb_exit_controller(rsb);
+ sunxi_rsb_hw_exit(rsb);
+
+ return 0;
+}
+
+static int __maybe_unused sunxi_rsb_resume(struct device *dev)
+{
+ struct sunxi_rsb *rsb = dev_get_drvdata(dev);
+
+ return sunxi_rsb_init_controller(rsb);
+ return sunxi_rsb_hw_init(rsb);
+}
+
static int sunxi_rsb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -756,6 +773,17 @@ static int sunxi_rsb_remove(struct platf
return 0;
}
+static void sunxi_rsb_shutdown(struct platform_device *pdev)
+{
+ struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+
+ sunxi_rsb_hw_exit(rsb);
+}
+
+static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sunxi_rsb_suspend, sunxi_rsb_resume)
+};
+
static int sunxi_rsb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -738,8 +757,9 @@ static struct platform_driver sunxi_rsb_
static const struct of_device_id sunxi_rsb_of_match_table[] = {
{ .compatible = "allwinner,sun8i-a23-rsb" },
{}
@@ -765,9 +793,11 @@ MODULE_DEVICE_TABLE(of, sunxi_rsb_of_mat
static struct platform_driver sunxi_rsb_driver = {
.probe = sunxi_rsb_probe,
.remove = sunxi_rsb_remove,
+ .shutdown = sunxi_rsb_shutdown,
.driver = {
- .name = RSB_CTRL_NAME,
+ .name = RSB_CTRL_NAME,
.name = RSB_CTRL_NAME,
.of_match_table = sunxi_rsb_of_match_table,
+ .pm = &sunxi_rsb_dev_pm_ops,
+ .pm = &sunxi_rsb_dev_pm_ops,
},
};

View File

@ -1,12 +1,14 @@
From f226c7c38ef1b9ae026680c9c68fedd4fbd4ecd7 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 1 Jan 2020 00:10:40 -0600
Subject: [PATCH 14/31] bus: sunxi-rsb: Implement runtime power management
Subject: [PATCH] bus: sunxi-rsb: Implement runtime power management
Gate the clock to save power while the controller is idle.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/bus/sunxi-rsb.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
drivers/bus/sunxi-rsb.c | 44 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@ -18,42 +20,57 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
@@ -334,6 +335,7 @@ static int regmap_sunxi_rsb_reg_read(voi
if (reg > 0xff)
@@ -337,6 +338,10 @@ static int sunxi_rsb_read(struct sunxi_r
return -EINVAL;
}
+ pm_runtime_get_sync(rsb->dev);
+ ret = pm_runtime_resume_and_get(rsb->dev);
+ if (ret)
+ return ret;
+
mutex_lock(&rsb->lock);
writel(reg, rsb->regs + RSB_ADDR);
@@ -348,6 +350,8 @@ static int regmap_sunxi_rsb_reg_read(voi
writel(addr, rsb->regs + RSB_ADDR);
@@ -352,6 +357,9 @@ static int sunxi_rsb_read(struct sunxi_r
unlock:
mutex_unlock(&rsb->lock);
+ pm_runtime_mark_last_busy(rsb->dev);
+ pm_runtime_put_autosuspend(rsb->dev);
+
return ret;
}
@@ -363,6 +367,7 @@ static int regmap_sunxi_rsb_reg_write(vo
if (reg > 0xff)
return -EINVAL;
+ pm_runtime_get_sync(rsb->dev);
@@ -379,6 +387,10 @@ static int sunxi_rsb_write(struct sunxi_
return -EINVAL;
}
+ ret = pm_runtime_resume_and_get(rsb->dev);
+ if (ret)
+ return ret;
+
mutex_lock(&rsb->lock);
writel(reg, rsb->regs + RSB_ADDR);
@@ -373,6 +378,8 @@ static int regmap_sunxi_rsb_reg_write(vo
ret = _sunxi_rsb_run_xfer(rsb);
writel(addr, rsb->regs + RSB_ADDR);
@@ -389,6 +401,9 @@ static int sunxi_rsb_write(struct sunxi_
mutex_unlock(&rsb->lock);
+ pm_runtime_mark_last_busy(rsb->dev);
+ pm_runtime_put_autosuspend(rsb->dev);
+
return ret;
}
@@ -649,10 +656,30 @@ static int sunxi_rsb_exit_controller(str
return 0;
@@ -672,10 +687,29 @@ err_clk_disable:
static void sunxi_rsb_hw_exit(struct sunxi_rsb *rsb)
{
+ /* Keep the clock and PM reference counts consistent. */
+ if (pm_runtime_status_suspended(rsb->dev))
+ pm_runtime_resume(rsb->dev);
reset_control_assert(rsb->rstc);
clk_disable_unprepare(rsb->clk);
}
+static int __maybe_unused sunxi_rsb_runtime_suspend(struct device *dev)
@ -75,15 +92,33 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
static int __maybe_unused sunxi_rsb_suspend(struct device *dev)
{
struct sunxi_rsb *rsb = dev_get_drvdata(dev);
@@ -758,6 +792,12 @@ static int sunxi_rsb_probe(struct platfo
if (ret)
dev_warn(dev, "Initialize device mode failed: %d\n", ret);
+ /* Ensure the clock is running before asserting reset. */
+ if (pm_runtime_status_suspended(dev))
+ pm_runtime_resume(dev);
+ pm_suspend_ignore_children(dev, true);
+ pm_runtime_set_active(dev);
+ pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
+
return sunxi_rsb_exit_controller(rsb);
}
of_rsb_register_devices(rsb);
@@ -664,6 +691,8 @@ static int __maybe_unused sunxi_rsb_resu
return 0;
@@ -768,6 +808,7 @@ static int sunxi_rsb_remove(struct platf
struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
+ pm_runtime_disable(&pdev->dev);
sunxi_rsb_hw_exit(rsb);
return 0;
@@ -777,10 +818,13 @@ static void sunxi_rsb_shutdown(struct pl
{
struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+ pm_runtime_disable(&pdev->dev);
sunxi_rsb_hw_exit(rsb);
}
static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
@ -92,31 +127,3 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sunxi_rsb_suspend, sunxi_rsb_resume)
};
@@ -734,6 +763,12 @@ static int sunxi_rsb_probe(struct platfo
of_rsb_register_devices(rsb);
+ pm_suspend_ignore_children(dev, true);
+ pm_runtime_set_autosuspend_delay(dev, 1000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
return 0;
}
@@ -741,9 +776,14 @@ static int sunxi_rsb_remove(struct platf
{
struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+ pm_runtime_get_sync(&pdev->dev);
+
device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
sunxi_rsb_exit_controller(rsb);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
return 0;
}

View File

@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 2 Jan 2021 15:52:27 -0600
Subject: [PATCH] rtc: sun6i: Allow RTC wakeup after shutdown
Only IRQs that have enable_irq_wake() called on them can wake the system
from sleep or after it has been shut down. Currently, the RTC alarm can
only wake the system from sleep. Run the suspend callback to arm the IRQ
during the shutdown process, so the RTC alarm also works after shutdown.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/rtc/rtc-sun6i.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -639,7 +639,6 @@ static const struct rtc_class_ops sun6i_
.alarm_irq_enable = sun6i_rtc_alarm_irq_enable
};
-#ifdef CONFIG_PM_SLEEP
/* Enable IRQ wake on suspend, to wake up from RTC. */
static int sun6i_rtc_suspend(struct device *dev)
{
@@ -652,7 +651,7 @@ static int sun6i_rtc_suspend(struct devi
}
/* Disable IRQ wake on resume. */
-static int sun6i_rtc_resume(struct device *dev)
+static int __maybe_unused sun6i_rtc_resume(struct device *dev)
{
struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
@@ -661,7 +660,6 @@ static int sun6i_rtc_resume(struct devic
return 0;
}
-#endif
static SIMPLE_DEV_PM_OPS(sun6i_rtc_pm_ops,
sun6i_rtc_suspend, sun6i_rtc_resume);
@@ -733,6 +731,11 @@ static int sun6i_rtc_probe(struct platfo
return 0;
}
+static void sun6i_rtc_shutdown(struct platform_device *pdev)
+{
+ sun6i_rtc_suspend(&pdev->dev);
+}
+
/*
* As far as RTC functionality goes, all models are the same. The
* datasheets claim that different models have different number of
@@ -753,6 +756,7 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids
static struct platform_driver sun6i_rtc_driver = {
.probe = sun6i_rtc_probe,
+ .shutdown = sun6i_rtc_shutdown,
.driver = {
.name = "sun6i-rtc",
.of_match_table = sun6i_rtc_dt_ids,

View File

@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 22 Oct 2019 00:15:41 +0200
Subject: [PATCH] input: sun4i-lradc-keys - Add wakup support
Allow the driver to wake the system on key press if the "wakeup-source"
property is provided in the device tree. Using the LRADC as a wakeup
source requires keeping the AVCC domain active during sleep. Since this
has a nontrivial impact on power consumption (sometimes doubling it),
disable the LRADC wakeup source by default.
Signed-off-by: Ondrej Jirman <megous@megous.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/input/keyboard/sun4i-lradc-keys.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
--- a/drivers/input/keyboard/sun4i-lradc-keys.c
+++ b/drivers/input/keyboard/sun4i-lradc-keys.c
@@ -22,6 +22,8 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/pm_wakeup.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@@ -226,8 +228,7 @@ static int sun4i_lradc_probe(struct plat
{
struct sun4i_lradc_data *lradc;
struct device *dev = &pdev->dev;
- int i;
- int error;
+ int error, i, irq;
lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL);
if (!lradc)
@@ -272,8 +273,13 @@ static int sun4i_lradc_probe(struct plat
if (IS_ERR(lradc->base))
return PTR_ERR(lradc->base);
- error = devm_request_irq(dev, platform_get_irq(pdev, 0),
- sun4i_lradc_irq, 0,
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Failed to get IRQ\n");
+ return irq;
+ }
+
+ error = devm_request_irq(dev, irq, sun4i_lradc_irq, 0,
"sun4i-a10-lradc-keys", lradc);
if (error)
return error;
@@ -282,6 +288,14 @@ static int sun4i_lradc_probe(struct plat
if (error)
return error;
+ if (device_property_read_bool(dev, "wakeup-source")) {
+ device_set_wakeup_capable(dev, true);
+
+ error = dev_pm_set_wake_irq(dev, irq);
+ if (error)
+ dev_warn(dev, "Failed to set wake IRQ\n");
+ }
+
return 0;
}

View File

@ -1,8 +1,7 @@
From fef8b000f7e05397399b78891f26c53a2581863a Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Tue, 5 Mar 2019 22:02:41 -0600
Subject: [PATCH 27/31] firmware: arm_scpi: Support unidirectional mailbox
channels
Subject: [PATCH] firmware: arm_scpi: Support unidirectional mailbox channels
Some mailbox controllers have only unidirectional channels, so we need a
pair of them for each SCPI channel. If a mbox-names property is present,

View File

@ -1,7 +1,7 @@
From 13bd8de3e31b42b4a44310294a29c620f36936ba Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 1 Jan 2020 16:12:36 -0600
Subject: [PATCH 29/31] ARM: dts: sunxi: h3/h5: Add SCPI protocol
Subject: [PATCH] ARM: dts: sunxi: h3/h5: Add SCPI protocol
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

View File

@ -1,7 +1,7 @@
From f0550a4bd9eefe64469813d81a1549ba31182ad7 Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 14 Dec 2019 20:52:53 -0600
Subject: [PATCH 30/31] arm64: dts: allwinner: a64: Add SCPI protocol
Subject: [PATCH] arm64: dts: allwinner: a64: Add SCPI protocol
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

View File

@ -1,7 +1,7 @@
From d39c105f72223beb931088032b82114c6ad01cba Mon Sep 17 00:00:00 2001
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 14 Dec 2019 20:54:40 -0600
Subject: [PATCH 31/31] arm64: dts: allwinner: h6: Add SCPI protocol
Subject: [PATCH] arm64: dts: allwinner: h6: Add SCPI protocol
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

View File

@ -29,11 +29,13 @@ devices = \
},
'pine64': {
'dtb': 'sun50i-a64-pine64.dtb',
'config': 'pine64_plus_defconfig'
'config': 'pine64_plus_defconfig',
'crust_config': 'pine64_plus_defconfig'
},
'pine64-lts': {
'dtb': 'sun50i-a64-pine64-lts.dtb',
'config': 'pine64-lts_defconfig'
'config': 'pine64-lts_defconfig',
'crust_config': 'pine64_plus_defconfig'
},
'pine64-plus': {
'dtb': 'sun50i-a64-pine64-plus.dtb',