mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-03-31 14:41:55 -07:00
Allwinner: linux: Update patches related to power management
This commit is contained in:
@@ -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,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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user