mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Merge pull request #4991 from jernejsk/crust-updt
Allwinner: Improve suspend/resume
This commit is contained in:
commit
e417de73bf
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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).
|
@ -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>;
|
||||
};
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
---
|
@ -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>
|
||||
---
|
@ -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
|
@ -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>
|
||||
---
|
@ -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,
|
||||
},
|
||||
};
|
@ -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();
|
||||
}
|
||||
|
@ -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",
|
@ -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,
|
||||
},
|
||||
};
|
@ -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[] = {
|
@ -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,
|
@ -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, ®);
|
||||
@@ -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;
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
@ -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;
|
||||
}
|
@ -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,
|
@ -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,
|
||||
},
|
||||
};
|
@ -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.
|
@ -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.
|
@ -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>
|
||||
---
|
@ -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:
|
@ -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>
|
||||
---
|
@ -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;
|
||||
+}
|
||||
|
@ -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);
|
||||
|
@ -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 = <®_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 = <®_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 = <®_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 = <®_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 = <®_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 = <®_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 = <®_dcdc1>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
@ -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
|
@ -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 = <®_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 = <®_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 = <®_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 = <®_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 = <®_dcdc1>;
|
||||
swin-supply = <®_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 = <®_dcdc1>;
|
||||
fldoin-supply = <®_dcdc5>;
|
||||
swin-supply = <®_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 = <®_dcdc1>;
|
||||
swin-supply = <®_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 = <®_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 = <®_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 = <®_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 = <®_dcdc1>;
|
||||
drivevbus-supply = <®_vcc5v0>;
|
||||
x-powers,drive-vbus-en;
|
@ -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>;
|
||||
+ };
|
@ -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;
|
@ -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";
|
@ -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>;
|
||||
};
|
@ -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;
|
@ -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>;
|
@ -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 {
|
@ -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";
|
@ -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
|
@ -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.
|
@ -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);
|
@ -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>;
|
||||
};
|
@ -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
|
@ -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";
|
@ -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";
|
@ -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";
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
@ -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>
|
||||
---
|
@ -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>
|
||||
---
|
@ -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>
|
||||
---
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user