Linux GPIO subsystem development
 help / color / mirror / Atom feed
* [PATCH v9 12/22] cpufreq: tegra124: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch adds suspend and resume pm ops for cpufreq driver.

PLLP is the safe clock source for CPU during system suspend and
resume as PLLP rate is below the CPU Fmax at Vmin.

CPUFreq driver suspend switches the CPU clock source to PLLP and
disables the DFLL clock.

During system resume, warmboot code powers up the CPU with PLLP
clock source. So CPUFreq driver resume enabled DFLL clock and
switches CPU back to DFLL clock source.

Acked-by: Thierry Reding <treding@nvidia.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/cpufreq/tegra124-cpufreq.c | 59 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/cpufreq/tegra124-cpufreq.c b/drivers/cpufreq/tegra124-cpufreq.c
index 4f0c637b3b49..7a1ea6fdcab6 100644
--- a/drivers/cpufreq/tegra124-cpufreq.c
+++ b/drivers/cpufreq/tegra124-cpufreq.c
@@ -6,6 +6,7 @@
 #define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
 
 #include <linux/clk.h>
+#include <linux/cpufreq.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -128,8 +129,66 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static int __maybe_unused tegra124_cpufreq_suspend(struct device *dev)
+{
+	struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+	int err;
+
+	/*
+	 * PLLP rate 408Mhz is below the CPU Fmax at Vmin and is safe to
+	 * use during suspend and resume. So, switch the CPU clock source
+	 * to PLLP and disable DFLL.
+	 */
+	err = clk_set_parent(priv->cpu_clk, priv->pllp_clk);
+	if (err < 0) {
+		dev_err(dev, "failed to reparent to PLLP: %d\n", err);
+		return err;
+	}
+
+	clk_disable_unprepare(priv->dfll_clk);
+
+	return 0;
+}
+
+static int __maybe_unused tegra124_cpufreq_resume(struct device *dev)
+{
+	struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+	int err;
+
+	/*
+	 * Warmboot code powers up the CPU with PLLP clock source.
+	 * Enable DFLL clock and switch CPU clock source back to DFLL.
+	 */
+	err = clk_prepare_enable(priv->dfll_clk);
+	if (err < 0) {
+		dev_err(dev, "failed to enable DFLL clock for CPU: %d\n", err);
+		goto disable_cpufreq;
+	}
+
+	err = clk_set_parent(priv->cpu_clk, priv->dfll_clk);
+	if (err < 0) {
+		dev_err(dev, "failed to reparent to DFLL clock: %d\n", err);
+		goto disable_dfll;
+	}
+
+	return 0;
+
+disable_dfll:
+	clk_disable_unprepare(priv->dfll_clk);
+disable_cpufreq:
+	disable_cpufreq();
+
+	return err;
+}
+
+static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
+				tegra124_cpufreq_resume)
+};
+
 static struct platform_driver tegra124_cpufreq_platdrv = {
 	.driver.name	= "cpufreq-tegra124",
+	.driver.pm	= &tegra124_cpufreq_pm_ops,
 	.probe		= tegra124_cpufreq_probe,
 };
 
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 14/22] clk: tegra: Share clk and rst register defines with Tegra clock driver
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

Move CLK_OUT_ENB and RST_DEVICES registers to clk.h to share these with
Tegra clock driver.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk.c | 45 ---------------------------------------------
 drivers/clk/tegra/clk.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index eb08047fd02f..33ac88ee324a 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -16,51 +16,6 @@
 
 #include "clk.h"
 
-#define CLK_OUT_ENB_L			0x010
-#define CLK_OUT_ENB_H			0x014
-#define CLK_OUT_ENB_U			0x018
-#define CLK_OUT_ENB_V			0x360
-#define CLK_OUT_ENB_W			0x364
-#define CLK_OUT_ENB_X			0x280
-#define CLK_OUT_ENB_Y			0x298
-#define CLK_ENB_PLLP_OUT_CPU		BIT(31)
-#define CLK_OUT_ENB_SET_L		0x320
-#define CLK_OUT_ENB_CLR_L		0x324
-#define CLK_OUT_ENB_SET_H		0x328
-#define CLK_OUT_ENB_CLR_H		0x32c
-#define CLK_OUT_ENB_SET_U		0x330
-#define CLK_OUT_ENB_CLR_U		0x334
-#define CLK_OUT_ENB_SET_V		0x440
-#define CLK_OUT_ENB_CLR_V		0x444
-#define CLK_OUT_ENB_SET_W		0x448
-#define CLK_OUT_ENB_CLR_W		0x44c
-#define CLK_OUT_ENB_SET_X		0x284
-#define CLK_OUT_ENB_CLR_X		0x288
-#define CLK_OUT_ENB_SET_Y		0x29c
-#define CLK_OUT_ENB_CLR_Y		0x2a0
-
-#define RST_DEVICES_L			0x004
-#define RST_DEVICES_H			0x008
-#define RST_DEVICES_U			0x00C
-#define RST_DEVICES_V			0x358
-#define RST_DEVICES_W			0x35C
-#define RST_DEVICES_X			0x28C
-#define RST_DEVICES_Y			0x2a4
-#define RST_DEVICES_SET_L		0x300
-#define RST_DEVICES_CLR_L		0x304
-#define RST_DEVICES_SET_H		0x308
-#define RST_DEVICES_CLR_H		0x30c
-#define RST_DEVICES_SET_U		0x310
-#define RST_DEVICES_CLR_U		0x314
-#define RST_DEVICES_SET_V		0x430
-#define RST_DEVICES_CLR_V		0x434
-#define RST_DEVICES_SET_W		0x438
-#define RST_DEVICES_CLR_W		0x43c
-#define RST_DEVICES_SET_X		0x290
-#define RST_DEVICES_CLR_X		0x294
-#define RST_DEVICES_SET_Y		0x2a8
-#define RST_DEVICES_CLR_Y		0x2ac
-
 /* Global data of Tegra CPU CAR ops */
 static struct tegra_cpu_car_ops dummy_car_ops;
 struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 55c4b78280be..ba123ba4a1da 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -10,6 +10,51 @@
 #include <linux/clkdev.h>
 #include <linux/delay.h>
 
+#define CLK_OUT_ENB_L			0x010
+#define CLK_OUT_ENB_H			0x014
+#define CLK_OUT_ENB_U			0x018
+#define CLK_OUT_ENB_V			0x360
+#define CLK_OUT_ENB_W			0x364
+#define CLK_OUT_ENB_X			0x280
+#define CLK_OUT_ENB_Y			0x298
+#define CLK_ENB_PLLP_OUT_CPU		BIT(31)
+#define CLK_OUT_ENB_SET_L		0x320
+#define CLK_OUT_ENB_CLR_L		0x324
+#define CLK_OUT_ENB_SET_H		0x328
+#define CLK_OUT_ENB_CLR_H		0x32c
+#define CLK_OUT_ENB_SET_U		0x330
+#define CLK_OUT_ENB_CLR_U		0x334
+#define CLK_OUT_ENB_SET_V		0x440
+#define CLK_OUT_ENB_CLR_V		0x444
+#define CLK_OUT_ENB_SET_W		0x448
+#define CLK_OUT_ENB_CLR_W		0x44c
+#define CLK_OUT_ENB_SET_X		0x284
+#define CLK_OUT_ENB_CLR_X		0x288
+#define CLK_OUT_ENB_SET_Y		0x29c
+#define CLK_OUT_ENB_CLR_Y		0x2a0
+
+#define RST_DEVICES_L			0x004
+#define RST_DEVICES_H			0x008
+#define RST_DEVICES_U			0x00C
+#define RST_DEVICES_V			0x358
+#define RST_DEVICES_W			0x35C
+#define RST_DEVICES_X			0x28C
+#define RST_DEVICES_Y			0x2a4
+#define RST_DEVICES_SET_L		0x300
+#define RST_DEVICES_CLR_L		0x304
+#define RST_DEVICES_SET_H		0x308
+#define RST_DEVICES_CLR_H		0x30c
+#define RST_DEVICES_SET_U		0x310
+#define RST_DEVICES_CLR_U		0x314
+#define RST_DEVICES_SET_V		0x430
+#define RST_DEVICES_CLR_V		0x434
+#define RST_DEVICES_SET_W		0x438
+#define RST_DEVICES_CLR_W		0x43c
+#define RST_DEVICES_SET_X		0x290
+#define RST_DEVICES_CLR_X		0x294
+#define RST_DEVICES_SET_Y		0x2a8
+#define RST_DEVICES_CLR_Y		0x2ac
+
 /**
  * struct tegra_clk_sync_source - external clock source from codec
  *
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 18/22] arm64: tegra: Enable wake from deep sleep on RTC alarm
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch updates device tree for RTC and PMC to allow system wake
from deep sleep on RTC alarm.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 659753118e96..30a7c48385a2 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -768,7 +768,8 @@
 	rtc@7000e000 {
 		compatible = "nvidia,tegra210-rtc", "nvidia,tegra20-rtc";
 		reg = <0x0 0x7000e000 0x0 0x100>;
-		interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&pmc>;
 		clocks = <&tegra_car TEGRA210_CLK_RTC>;
 		clock-names = "rtc";
 	};
@@ -778,6 +779,8 @@
 		reg = <0x0 0x7000e400 0x0 0x400>;
 		clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
 		clock-names = "pclk", "clk32k_in";
+		#interrupt-cells = <2>;
+		interrupt-controller;
 
 		powergates {
 			pd_audio: aud {
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 17/22] soc/tegra: pmc: Add pmc wake support for tegra210
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch implements PMC wakeup sequence for Tegra210 and defines
common used RTC alarm wake event.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 91c84d0e66ae..76e7292ded25 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -58,6 +58,11 @@
 #define  PMC_CNTRL_SYSCLK_POLARITY	BIT(10) /* sys clk polarity */
 #define  PMC_CNTRL_MAIN_RST		BIT(4)
 
+#define PMC_WAKE_MASK			0x0c
+#define PMC_WAKE_LEVEL			0x10
+#define PMC_WAKE_STATUS			0x14
+#define PMC_SW_WAKE_STATUS		0x18
+
 #define DPD_SAMPLE			0x020
 #define  DPD_SAMPLE_ENABLE		BIT(0)
 #define  DPD_SAMPLE_DISABLE		(0 << 0)
@@ -87,6 +92,11 @@
 
 #define PMC_SCRATCH41			0x140
 
+#define PMC_WAKE2_MASK			0x160
+#define PMC_WAKE2_LEVEL			0x164
+#define PMC_WAKE2_STATUS		0x168
+#define PMC_SW_WAKE2_STATUS		0x16c
+
 #define PMC_SENSOR_CTRL			0x1b0
 #define  PMC_SENSOR_CTRL_SCRATCH_WRITE	BIT(2)
 #define  PMC_SENSOR_CTRL_ENABLE_RST	BIT(1)
@@ -1922,6 +1932,43 @@ static const struct irq_domain_ops tegra_pmc_irq_domain_ops = {
 	.alloc = tegra_pmc_irq_alloc,
 };
 
+static int tegra210_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+	struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
+	unsigned int offset, bit;
+	u32 value;
+
+	if (data->hwirq == ULONG_MAX)
+		return 0;
+
+	offset = data->hwirq / 32;
+	bit = data->hwirq % 32;
+
+	/* clear wake status */
+	tegra_pmc_writel(pmc, 0, PMC_SW_WAKE_STATUS);
+	tegra_pmc_writel(pmc, 0, PMC_SW_WAKE2_STATUS);
+
+	tegra_pmc_writel(pmc, 0, PMC_WAKE_STATUS);
+	tegra_pmc_writel(pmc, 0, PMC_WAKE2_STATUS);
+
+	/* enable PMC wake */
+	if (data->hwirq >= 32)
+		offset = PMC_WAKE2_MASK;
+	else
+		offset = PMC_WAKE_MASK;
+
+	value = tegra_pmc_readl(pmc, offset);
+
+	if (on)
+		value |= BIT(bit);
+	else
+		value &= ~BIT(bit);
+
+	tegra_pmc_writel(pmc, value, offset);
+
+	return 0;
+}
+
 static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
 {
 	struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
@@ -1954,6 +2001,49 @@ static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
 	return 0;
 }
 
+static int tegra210_pmc_irq_set_type(struct irq_data *data, unsigned int type)
+{
+	struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
+	unsigned int offset, bit;
+	u32 value;
+
+	if (data->hwirq == ULONG_MAX)
+		return 0;
+
+	offset = data->hwirq / 32;
+	bit = data->hwirq % 32;
+
+	if (data->hwirq >= 32)
+		offset = PMC_WAKE2_LEVEL;
+	else
+		offset = PMC_WAKE_LEVEL;
+
+	value = tegra_pmc_readl(pmc, offset);
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+	case IRQ_TYPE_LEVEL_HIGH:
+		value |= BIT(bit);
+		break;
+
+	case IRQ_TYPE_EDGE_FALLING:
+	case IRQ_TYPE_LEVEL_LOW:
+		value &= ~BIT(bit);
+		break;
+
+	case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING:
+		value ^= BIT(bit);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	tegra_pmc_writel(pmc, value, offset);
+
+	return 0;
+}
+
 static int tegra186_pmc_irq_set_type(struct irq_data *data, unsigned int type)
 {
 	struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
@@ -2540,6 +2630,10 @@ static const struct pinctrl_pin_desc tegra210_pin_descs[] = {
 	TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
 };
 
+static const struct tegra_wake_event tegra210_wake_events[] = {
+	TEGRA_WAKE_IRQ("rtc", 16, 2),
+};
+
 static const struct tegra_pmc_soc tegra210_pmc_soc = {
 	.num_powergates = ARRAY_SIZE(tegra210_powergates),
 	.powergates = tegra210_powergates,
@@ -2557,10 +2651,14 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
 	.regs = &tegra20_pmc_regs,
 	.init = tegra20_pmc_init,
 	.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+	.irq_set_wake = tegra210_pmc_irq_set_wake,
+	.irq_set_type = tegra210_pmc_irq_set_type,
 	.reset_sources = tegra210_reset_sources,
 	.num_reset_sources = ARRAY_SIZE(tegra210_reset_sources),
 	.reset_levels = NULL,
 	.num_reset_levels = 0,
+	.num_wake_events = ARRAY_SIZE(tegra210_wake_events),
+	.wake_events = tegra210_wake_events,
 };
 
 #define TEGRA186_IO_PAD_TABLE(_pad)					     \
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 19/22] soc/tegra: pmc: Configure core power request polarity
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch configures polarity of the core power request signal
in PMC control register based on the device tree property.

PMC asserts and de-asserts power request signal based on it polarity
when it need to power-up and power-down the core rail during SC7.

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 76e7292ded25..53ed70773872 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -56,6 +56,7 @@
 #define  PMC_CNTRL_SIDE_EFFECT_LP0	BIT(14) /* LP0 when CPU pwr gated */
 #define  PMC_CNTRL_SYSCLK_OE		BIT(11) /* system clock enable */
 #define  PMC_CNTRL_SYSCLK_POLARITY	BIT(10) /* sys clk polarity */
+#define  PMC_CNTRL_PWRREQ_POLARITY	BIT(8)
 #define  PMC_CNTRL_MAIN_RST		BIT(4)
 
 #define PMC_WAKE_MASK			0x0c
@@ -2290,6 +2291,11 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc)
 	else
 		value |= PMC_CNTRL_SYSCLK_POLARITY;
 
+	if (pmc->corereq_high)
+		value &= ~PMC_CNTRL_PWRREQ_POLARITY;
+	else
+		value |= PMC_CNTRL_PWRREQ_POLARITY;
+
 	/* configure the output polarity while the request is tristated */
 	tegra_pmc_writel(pmc, value, PMC_CNTRL);
 
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 20/22] soc/tegra: pmc: Configure deep sleep control settings
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

Tegra210 and prior Tegra chips have deep sleep entry and wakeup related
timings which are platform specific that should be configured before
entering into deep sleep.

Below are the timing specific configurations for deep sleep entry and
wakeup.
- Core rail power-on stabilization timer
- OSC clock stabilization timer after SOC rail power is stabilized.
- Core power off time is the minimum wake delay to keep the system
  in deep sleep state irrespective of any quick wake event.

These values depends on the discharge time of regulators and turn OFF
time of the PMIC to allow the complete system to finish entering into
deep sleep state.

These values vary based on the platform design and are specified
through the device tree.

This patch has implementation to configure these timings which are must
to have for proper deep sleep and wakeup operations.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 53ed70773872..710969043668 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -88,6 +88,8 @@
 
 #define PMC_CPUPWRGOOD_TIMER		0xc8
 #define PMC_CPUPWROFF_TIMER		0xcc
+#define PMC_COREPWRGOOD_TIMER		0x3c
+#define PMC_COREPWROFF_TIMER		0xe0
 
 #define PMC_PWR_DET_VALUE		0xe4
 
@@ -2277,7 +2279,7 @@ static const struct tegra_pmc_regs tegra20_pmc_regs = {
 
 static void tegra20_pmc_init(struct tegra_pmc *pmc)
 {
-	u32 value;
+	u32 value, osc, pmu, off;
 
 	/* Always enable CPU power request */
 	value = tegra_pmc_readl(pmc, PMC_CNTRL);
@@ -2303,6 +2305,16 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc)
 	value = tegra_pmc_readl(pmc, PMC_CNTRL);
 	value |= PMC_CNTRL_SYSCLK_OE;
 	tegra_pmc_writel(pmc, value, PMC_CNTRL);
+
+	/* program core timings which are applicable only for suspend state */
+	if (pmc->suspend_mode != TEGRA_SUSPEND_NONE) {
+		osc = DIV_ROUND_UP(pmc->core_osc_time * 8192, 1000000);
+		pmu = DIV_ROUND_UP(pmc->core_pmu_time * 32768, 1000000);
+		off = DIV_ROUND_UP(pmc->core_off_time * 32768, 1000000);
+		tegra_pmc_writel(pmc, ((osc << 8) & 0xff00) | (pmu & 0xff),
+				 PMC_COREPWRGOOD_TIMER);
+		tegra_pmc_writel(pmc, off, PMC_COREPWROFF_TIMER);
+	}
 }
 
 static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 21/22] arm64: dts: tegra210-p2180: Jetson TX1 SC7 timings
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch has Jetson TX1 platform specific SC7 timing configuration
in device tree.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
index 27723829d033..cb58f79deb48 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
@@ -279,6 +279,13 @@
 
 	pmc@7000e400 {
 		nvidia,invert-interrupt;
+		nvidia,suspend-mode = <0>;
+		nvidia,cpu-pwr-good-time = <0>;
+		nvidia,cpu-pwr-off-time = <0>;
+		nvidia,core-pwr-good-time = <4587 3876>;
+		nvidia,core-pwr-off-time = <39065>;
+		nvidia,core-power-req-active-high;
+		nvidia,sys-clock-req-active-high;
 	};
 
 	/* eMMC */
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 22/22] arm64: dts: tegra210-p3450: Jetson Nano SC7 timings
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch adds Jetson Nano platform specific SC7 timing configuration
in the device tree.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts
index 9d17ec707bce..b525e69c172a 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts
@@ -382,6 +382,13 @@
 
 	pmc@7000e400 {
 		nvidia,invert-interrupt;
+		nvidia,suspend-mode = <0>;
+		nvidia,cpu-pwr-good-time = <0>;
+		nvidia,cpu-pwr-off-time = <0>;
+		nvidia,core-pwr-good-time = <4587 3876>;
+		nvidia,core-pwr-off-time = <39065>;
+		nvidia,core-power-req-active-high;
+		nvidia,sys-clock-req-active-high;
 	};
 
 	hda@70030000 {
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 15/22] clk: tegra210: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch adds support for clk: tegra210: suspend-resume.

All the CAR controller settings are lost on suspend when core
power goes off.

This patch has implementation for saving and restoring all PLLs
and clocks context during system suspend and resume to have the
clocks back to same state for normal operation.

Clock driver suspend and resume are registered as syscore_ops as clocks
restore need to happen before the other drivers resume to have all their
clocks back to the same state as before suspend.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk-tegra210.c | 96 ++++++++++++++++++++++++++++++++++++++--
 drivers/clk/tegra/clk.c          | 55 +++++++++++++++++++++++
 drivers/clk/tegra/clk.h          | 16 +++++++
 3 files changed, 163 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 4c9538bd28ad..d28d99cb0e9c 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -9,13 +9,13 @@
 #include <linux/clkdev.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/syscore_ops.h>
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/clk/tegra.h>
 #include <dt-bindings/clock/tegra210-car.h>
 #include <dt-bindings/reset/tegra210-car.h>
-#include <linux/iopoll.h>
 #include <linux/sizes.h>
 #include <soc/tegra/pmc.h>
 
@@ -220,11 +220,15 @@
 #define CLK_M_DIVISOR_SHIFT 2
 #define CLK_M_DIVISOR_MASK 0x3
 
+#define CLK_MASK_ARM	0x44
+#define MISC_CLK_ENB	0x48
+
 #define RST_DFLL_DVCO 0x2f4
 #define DVFS_DFLL_RESET_SHIFT 0
 
 #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
+#define CPU_SOFTRST_CTRL 0x380
 
 #define LVL2_CLK_GATE_OVRA 0xf8
 #define LVL2_CLK_GATE_OVRC 0x3a0
@@ -2825,6 +2829,7 @@ static int tegra210_enable_pllu(void)
 	struct tegra_clk_pll_freq_table *fentry;
 	struct tegra_clk_pll pllu;
 	u32 reg;
+	int ret;
 
 	for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) {
 		if (fentry->input_rate == pll_ref_freq)
@@ -2853,9 +2858,14 @@ static int tegra210_enable_pllu(void)
 	reg |= PLL_ENABLE;
 	writel(reg, clk_base + PLLU_BASE);
 
-	readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,
-					  reg & PLL_BASE_LOCK, 2, 1000);
-	if (!(reg & PLL_BASE_LOCK)) {
+	/*
+	 * During clocks resume, same PLLU init and enable sequence get
+	 * executed. So, readx_poll_timeout_atomic can't be used here as it
+	 * uses ktime_get() and timekeeping resume doesn't happen by that
+	 * time. So, using tegra210_wait_for_mask for PLL LOCK.
+	 */
+	ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK);
+	if (ret) {
 		pr_err("Timed out waiting for PLL_U to lock\n");
 		return -ETIMEDOUT;
 	}
@@ -3287,6 +3297,77 @@ static void tegra210_disable_cpu_clock(u32 cpu)
 }
 
 #ifdef CONFIG_PM_SLEEP
+#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) + ((_off) * 4))
+#define car_writel(_val, _base, _off) \
+		writel_relaxed(_val, clk_base + (_base) + ((_off) * 4))
+
+static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx;
+static u32 cpu_softrst_ctx[3];
+
+static int tegra210_clk_suspend(void)
+{
+	unsigned int i;
+
+	clk_save_context();
+
+	/*
+	 * Save the bootloader configured clock registers SPARE_REG0,
+	 * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL.
+	 */
+	spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0);
+	misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB);
+	clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM);
+
+	for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
+		cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i);
+
+	tegra_clk_periph_suspend();
+	return 0;
+}
+
+static void tegra210_clk_resume(void)
+{
+	unsigned int i;
+
+	tegra_clk_osc_resume(clk_base);
+
+	/*
+	 * Restore the bootloader configured clock registers SPARE_REG0,
+	 * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context.
+	 */
+	writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0);
+	writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB);
+	writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM);
+
+	for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
+		car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i);
+
+	/*
+	 * Tegra clock programming sequence recommends peripheral clock to
+	 * be enabled prior to changing its clock source and divider to
+	 * prevent glitchless frequency switch.
+	 * So, enable all peripheral clocks before restoring their source
+	 * and dividers.
+	 */
+	writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_L, clk_base + CLK_OUT_ENB_L);
+	writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_H, clk_base + CLK_OUT_ENB_H);
+	writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_U, clk_base + CLK_OUT_ENB_U);
+	writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_V, clk_base + CLK_OUT_ENB_V);
+	writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_W, clk_base + CLK_OUT_ENB_W);
+	writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_X, clk_base + CLK_OUT_ENB_X);
+	writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_Y, clk_base + CLK_OUT_ENB_Y);
+
+	/* wait for all writes to happen to have all the clocks enabled */
+	fence_udelay(2, clk_base);
+
+	/* restore PLLs and all peripheral clock rates */
+	tegra210_init_pllu();
+	clk_restore_context();
+
+	/* restore saved context of peripheral clocks and reset state */
+	tegra_clk_periph_resume();
+}
+
 static void tegra210_cpu_clock_suspend(void)
 {
 	/* switch coresite to clk_m, save off original source */
@@ -3302,6 +3383,11 @@ static void tegra210_cpu_clock_resume(void)
 }
 #endif
 
+static struct syscore_ops tegra_clk_syscore_ops = {
+	.suspend = tegra210_clk_suspend,
+	.resume = tegra210_clk_resume,
+};
+
 static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {
 	.wait_for_reset	= tegra210_wait_cpu_in_reset,
 	.disable_clock	= tegra210_disable_cpu_clock,
@@ -3586,5 +3672,7 @@ static void __init tegra210_clock_init(struct device_node *np)
 	tegra210_mbist_clk_init();
 
 	tegra_cpu_car_ops = &tegra210_cpu_car_ops;
+
+	register_syscore_ops(&tegra_clk_syscore_ops);
 }
 CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index 33ac88ee324a..e6bd6d1ea012 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -22,6 +22,7 @@ struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
 
 int *periph_clk_enb_refcnt;
 static int periph_banks;
+static u32 *periph_state_ctx;
 static struct clk **clks;
 static int clk_num;
 static struct clk_onecell_data clk_data;
@@ -168,6 +169,52 @@ void tegra_clk_set_pllp_out_cpu(bool enable)
 	writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
 }
 
+void tegra_clk_periph_suspend(void)
+{
+	unsigned int i, idx;
+
+	idx = 0;
+	for (i = 0; i < periph_banks; i++, idx++)
+		periph_state_ctx[idx] =
+			readl_relaxed(clk_base + periph_regs[i].enb_reg);
+
+	for (i = 0; i < periph_banks; i++, idx++)
+		periph_state_ctx[idx] =
+			readl_relaxed(clk_base + periph_regs[i].rst_reg);
+}
+
+void tegra_clk_periph_resume(void)
+{
+	unsigned int i, idx;
+
+	idx = 0;
+	for (i = 0; i < periph_banks; i++, idx++)
+		writel_relaxed(periph_state_ctx[idx],
+			       clk_base + periph_regs[i].enb_reg);
+	/*
+	 * All non-boot peripherals will be in reset state on resume.
+	 * Wait for 5us of reset propagation delay before de-asserting
+	 * the peripherals based on the saved context.
+	 */
+	fence_udelay(5, clk_base);
+
+	for (i = 0; i < periph_banks; i++, idx++)
+		writel_relaxed(periph_state_ctx[idx],
+			       clk_base + periph_regs[i].rst_reg);
+
+	fence_udelay(2, clk_base);
+}
+
+static int tegra_clk_periph_ctx_init(int banks)
+{
+	periph_state_ctx = kcalloc(2 * banks, sizeof(*periph_state_ctx),
+				   GFP_KERNEL);
+	if (!periph_state_ctx)
+		return -ENOMEM;
+
+	return 0;
+}
+
 struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
 {
 	clk_base = regs;
@@ -189,6 +236,14 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
 
 	clk_num = num;
 
+	if (IS_ENABLED(CONFIG_PM_SLEEP)) {
+		if (tegra_clk_periph_ctx_init(banks)) {
+			kfree(periph_clk_enb_refcnt);
+			kfree(clks);
+			return NULL;
+		}
+	}
+
 	return clks;
 }
 
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index ba123ba4a1da..30247b8fe912 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -55,6 +55,20 @@
 #define RST_DEVICES_SET_Y		0x2a8
 #define RST_DEVICES_CLR_Y		0x2ac
 
+/*
+ * Tegra CLK_OUT_ENB registers have some undefined bits which are not used and
+ * any accidental write of 1 to these bits can cause PSLVERR.
+ * So below are the valid mask defines for each CLK_OUT_ENB register used to
+ * turn ON only the valid clocks.
+ */
+#define TEGRA210_CLK_ENB_VLD_MSK_L	0xdcd7dff9
+#define TEGRA210_CLK_ENB_VLD_MSK_H	0x87d1f3e7
+#define TEGRA210_CLK_ENB_VLD_MSK_U	0xf3fed3fa
+#define TEGRA210_CLK_ENB_VLD_MSK_V	0xffc18cfb
+#define TEGRA210_CLK_ENB_VLD_MSK_W	0x793fb7ff
+#define TEGRA210_CLK_ENB_VLD_MSK_X	0x3fe66fff
+#define TEGRA210_CLK_ENB_VLD_MSK_Y	0xfc1fc7ff
+
 /**
  * struct tegra_clk_sync_source - external clock source from codec
  *
@@ -880,6 +894,8 @@ int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
 		 u8 frac_width, u8 flags);
 void tegra_clk_osc_resume(void __iomem *clk_base);
 void tegra_clk_set_pllp_out_cpu(bool enable);
+void tegra_clk_periph_suspend(void);
+void tegra_clk_periph_resume(void);
 
 
 /* Combined read fence with delay */
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 16/22] soc/tegra: pmc: Allow to support more tegras wake
From: Sowjanya Komatineni @ 2019-08-16 19:42 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch allows to create separate irq_set_wake and irq_set_type
implementations for different tegra designs PMC that has different
wake models which require difference wake registers and different
programming sequence.

AOWAKE model support is available for Tegra186 and Tegra194 only
and it resides within PMC and supports tiered wake architecture.

Tegra210 and prior tegra designs uses PMC directly to receive wake
events and coordinate the wake sequence.

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 9f9c1c677cf4..91c84d0e66ae 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -226,6 +226,8 @@ struct tegra_pmc_soc {
 	void (*setup_irq_polarity)(struct tegra_pmc *pmc,
 				   struct device_node *np,
 				   bool invert);
+	int (*irq_set_wake)(struct irq_data *data, unsigned int on);
+	int (*irq_set_type)(struct irq_data *data, unsigned int type);
 
 	const char * const *reset_sources;
 	unsigned int num_reset_sources;
@@ -1920,7 +1922,7 @@ static const struct irq_domain_ops tegra_pmc_irq_domain_ops = {
 	.alloc = tegra_pmc_irq_alloc,
 };
 
-static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
+static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
 {
 	struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
 	unsigned int offset, bit;
@@ -1952,7 +1954,7 @@ static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
 	return 0;
 }
 
-static int tegra_pmc_irq_set_type(struct irq_data *data, unsigned int type)
+static int tegra186_pmc_irq_set_type(struct irq_data *data, unsigned int type)
 {
 	struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
 	u32 value;
@@ -2006,8 +2008,8 @@ static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
 	pmc->irq.irq_unmask = irq_chip_unmask_parent;
 	pmc->irq.irq_eoi = irq_chip_eoi_parent;
 	pmc->irq.irq_set_affinity = irq_chip_set_affinity_parent;
-	pmc->irq.irq_set_type = tegra_pmc_irq_set_type;
-	pmc->irq.irq_set_wake = tegra_pmc_irq_set_wake;
+	pmc->irq.irq_set_type = pmc->soc->irq_set_type;
+	pmc->irq.irq_set_wake = pmc->soc->irq_set_wake;
 
 	pmc->domain = irq_domain_add_hierarchy(parent, 0, 96, pmc->dev->of_node,
 					       &tegra_pmc_irq_domain_ops, pmc);
@@ -2680,6 +2682,8 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
 	.regs = &tegra186_pmc_regs,
 	.init = NULL,
 	.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+	.irq_set_wake = tegra186_pmc_irq_set_wake,
+	.irq_set_type = tegra186_pmc_irq_set_type,
 	.reset_sources = tegra186_reset_sources,
 	.num_reset_sources = ARRAY_SIZE(tegra186_reset_sources),
 	.reset_levels = tegra186_reset_levels,
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 13/22] clk: tegra210: Use fence_udelay during PLLU init
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch uses fence_udelay rather than udelay during PLLU
initialization to ensure writes to clock registers happens before
waiting for specified delay.

Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk-tegra210.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index df172d5772d7..4c9538bd28ad 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -2841,7 +2841,7 @@ static int tegra210_enable_pllu(void)
 	reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]);
 	reg &= ~BIT(pllu.params->iddq_bit_idx);
 	writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]);
-	udelay(5);
+	fence_udelay(5, clk_base);
 
 	reg = readl_relaxed(clk_base + PLLU_BASE);
 	reg &= ~GENMASK(20, 0);
@@ -2849,7 +2849,7 @@ static int tegra210_enable_pllu(void)
 	reg |= fentry->n << 8;
 	reg |= fentry->p << 16;
 	writel(reg, clk_base + PLLU_BASE);
-	udelay(1);
+	fence_udelay(1, clk_base);
 	reg |= PLL_ENABLE;
 	writel(reg, clk_base + PLLU_BASE);
 
@@ -2895,12 +2895,12 @@ static int tegra210_init_pllu(void)
 		reg = readl_relaxed(clk_base + XUSB_PLL_CFG0);
 		reg &= ~XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK;
 		writel_relaxed(reg, clk_base + XUSB_PLL_CFG0);
-		udelay(1);
+		fence_udelay(1, clk_base);
 
 		reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0);
 		reg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE;
 		writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0);
-		udelay(1);
+		fence_udelay(1, clk_base);
 
 		reg = readl_relaxed(clk_base + PLLU_BASE);
 		reg &= ~PLLU_BASE_CLKENABLE_USB;
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 07/22] clk: Add API to get index of the clock parent
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch adds an API clk_hw_get_parent_index to get index of the
clock parent to use during the clock restore operations on system
resume.

Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/clk.c            | 17 +++++++++++++++++
 include/linux/clk-provider.h |  1 +
 2 files changed, 18 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index cbcc333aec84..12ad0e9b8591 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1645,6 +1645,23 @@ static int clk_fetch_parent_index(struct clk_core *core,
 	return i;
 }
 
+/**
+ * clk_hw_get_parent_index - return the index of parent clock
+ * @hw: clk_hw associated with the clk being consumed
+ * @parent_hw: clk_hw associated with the parent of clk
+ *
+ * Fetches and returns the index of parent clock.
+ * If hw or parent_hw is NULL, returns -EINVAL.
+ */
+int clk_hw_get_parent_index(struct clk_hw *hw, struct clk_hw *parent_hw)
+{
+	if (!hw || !parent_hw)
+		return -EINVAL;
+
+	return clk_fetch_parent_index(hw->core, parent_hw->core);
+}
+EXPORT_SYMBOL_GPL(clk_hw_get_parent_index);
+
 /*
  * Update the orphan status of @core and all its children.
  */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index dce5521a9bf6..cce830780900 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -817,6 +817,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
 					  unsigned int index);
+int clk_hw_get_parent_index(struct clk_hw *hw, struct clk_hw *parent_hw);
 int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent);
 unsigned int __clk_get_enable_count(struct clk *clk);
 unsigned long clk_hw_get_rate(const struct clk_hw *hw);
-- 
2.7.4


^ permalink raw reply related

* [PATCH v9 02/22] pinctrl: tegra: Flush pinctrl writes during resume
From: Sowjanya Komatineni @ 2019-08-16 19:41 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565984527-5272-1-git-send-email-skomatineni@nvidia.com>

This patch adds pinctrl register read to flush all the prior pinctrl
writes and then adds barrier for pinctrl register read to complete
during resume to make sure all pinctrl changes are effective.

Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/pinctrl/tegra/pinctrl-tegra.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
index 5e3c00137d71..e9a7cbb9aa33 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
@@ -677,6 +677,10 @@ static int tegra_pinctrl_resume(struct device *dev)
 			writel_relaxed(*backup_regs++, regs++);
 	}
 
+	/* flush all the prior writes */
+	readl_relaxed(pmx->regs[0]);
+	/* wait for pinctrl register read to complete */
+	rmb();
 	return 0;
 }
 
-- 
2.7.4


^ permalink raw reply related

* [PATCH] gpio: of: fix Freescale SPI CS quirk handling
From: Andreas Kemnade @ 2019-08-16 16:50 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, linux-gpio, linux-kernel,
	letux-kernel, linux-spi
  Cc: Andreas Kemnade, H . Nikolaus Schaller

On the gta04 we see:
spi_gpio: probe of spi_lcd failed with error -2

The quirk introduced in
commit e3023bf80639 ("gpio: of: Handle the Freescale SPI CS")
can also be triggered by a temporary -EPROBE_DEFER and
so "convert" it to a hard -ENOENT.

Disable that conversion by checking for -EPROBE_DEFER.

Fixes: e3023bf80639 ("gpio: of: Handle the Freescale SPI CS")
Suggested-by: H. Nikolaus Schaller <hns@goldelico.com>
Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 drivers/gpio/gpiolib-of.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 567fb98c0892..9762dd6d99fa 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -363,7 +363,7 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
 	/* Special handling for SPI GPIOs if used */
 	if (IS_ERR(desc))
 		desc = of_find_spi_gpio(dev, con_id, &of_flags);
-	if (IS_ERR(desc)) {
+	if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER) {
 		/* This quirk looks up flags and all */
 		desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
 		if (!IS_ERR(desc))
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH 1/7] [RFC] ARM: remove Intel iop33x and iop13xx support
From: Aaro Koskinen @ 2019-08-16 16:15 UTC (permalink / raw)
  To: Russell King - ARM Linux admin
  Cc: Linus Walleij, Martin Michlmayr, Peter Teichmann, Arnd Bergmann,
	open list:GPIO SUBSYSTEM, Linux Kernel Mailing List, soc,
	Bartosz Golaszewski, Vinod Koul, linux-i2c, dmaengine,
	Dan Williams, Linux ARM
In-Reply-To: <20190816155833.GL13294@shell.armlinux.org.uk>

Hi,

On Fri, Aug 16, 2019 at 04:58:33PM +0100, Russell King - ARM Linux admin wrote:
> On Fri, Aug 16, 2019 at 06:42:49PM +0300, Aaro Koskinen wrote:
> > On Wed, Aug 14, 2019 at 10:36:01AM +0200, Linus Walleij wrote:
> > > On Mon, Aug 12, 2019 at 11:45 AM Martin Michlmayr <tbm@cyrius.com> wrote:
> > > > As Arnd points out, Debian used to have support for various iop32x
> > > > devices.  While Debian hasn't supported iop32x in a number of years,
> > > > these devices are still usable and in use (RMK being a prime example).
> > > 
> > > I suppose it could be a good idea to add support for iop32x to
> > > OpenWrt and/or OpenEmbedded, both of which support some
> > > pretty constrained systems.
> > 
> > This platform is not really too constrained... E.g. on N2100 you have
> > 512 MB RAM, SATA disks and gigabit ethernet. Not that different from
> > mvebu that Debian currently (?) supports. Maybe with multiplatform they
> > could support iop32x again.
> 
> Probably not.  The kernel has a dividing line between ARMv5 and ARMv6
> where it's not possible to multiplatform across that boundary, so
> you're already needing separate kernel images there.
> 
> Secondly, armhf distros won't be compatible with ARMv5, and to make
> them compatible will make performance on armhf suffer - you have to
> stop using barriers, exclusive load/store and a few other things.
> You have to rely on the kuser page exported by the kernel (which is
> now optional as it's deemed to be a security issue for ROP attacks)
> for some things that such a userspace requires - such as NPTL support.
> 
> Effectively, ARMv5 is an entirely separate userspace distro from armhf.

I thought they still had armel for ARMv5 and mvebu (kirkwood).

A.

^ permalink raw reply

* Re: [PATCH 1/7] [RFC] ARM: remove Intel iop33x and iop13xx support
From: Russell King - ARM Linux admin @ 2019-08-16 15:58 UTC (permalink / raw)
  To: Aaro Koskinen
  Cc: Linus Walleij, Martin Michlmayr, Peter Teichmann, Arnd Bergmann,
	open list:GPIO SUBSYSTEM, Linux Kernel Mailing List, soc,
	Bartosz Golaszewski, Vinod Koul, linux-i2c, dmaengine,
	Dan Williams, Linux ARM
In-Reply-To: <20190816154249.GA30291@darkstar.musicnaut.iki.fi>

On Fri, Aug 16, 2019 at 06:42:49PM +0300, Aaro Koskinen wrote:
> Hi,
> 
> On Wed, Aug 14, 2019 at 10:36:01AM +0200, Linus Walleij wrote:
> > On Mon, Aug 12, 2019 at 11:45 AM Martin Michlmayr <tbm@cyrius.com> wrote:
> > > As Arnd points out, Debian used to have support for various iop32x
> > > devices.  While Debian hasn't supported iop32x in a number of years,
> > > these devices are still usable and in use (RMK being a prime example).
> > 
> > I suppose it could be a good idea to add support for iop32x to
> > OpenWrt and/or OpenEmbedded, both of which support some
> > pretty constrained systems.
> 
> This platform is not really too constrained... E.g. on N2100 you have
> 512 MB RAM, SATA disks and gigabit ethernet. Not that different from
> mvebu that Debian currently (?) supports. Maybe with multiplatform they
> could support iop32x again.

Probably not.  The kernel has a dividing line between ARMv5 and ARMv6
where it's not possible to multiplatform across that boundary, so
you're already needing separate kernel images there.

Secondly, armhf distros won't be compatible with ARMv5, and to make
them compatible will make performance on armhf suffer - you have to
stop using barriers, exclusive load/store and a few other things.
You have to rely on the kuser page exported by the kernel (which is
now optional as it's deemed to be a security issue for ROP attacks)
for some things that such a userspace requires - such as NPTL support.

Effectively, ARMv5 is an entirely separate userspace distro from armhf.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

^ permalink raw reply

* Re: [PATCH 1/7] [RFC] ARM: remove Intel iop33x and iop13xx support
From: Aaro Koskinen @ 2019-08-16 15:42 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Martin Michlmayr, Peter Teichmann, Arnd Bergmann,
	open list:GPIO SUBSYSTEM, Linux Kernel Mailing List, soc,
	Russell King, Bartosz Golaszewski, Vinod Koul, linux-i2c,
	dmaengine, Dan Williams, Linux ARM
In-Reply-To: <CACRpkdao8LF8g5qi_h+9BT9cHwmB4OadabkdGfP0sEFeLbmiLw@mail.gmail.com>

Hi,

On Wed, Aug 14, 2019 at 10:36:01AM +0200, Linus Walleij wrote:
> On Mon, Aug 12, 2019 at 11:45 AM Martin Michlmayr <tbm@cyrius.com> wrote:
> > As Arnd points out, Debian used to have support for various iop32x
> > devices.  While Debian hasn't supported iop32x in a number of years,
> > these devices are still usable and in use (RMK being a prime example).
> 
> I suppose it could be a good idea to add support for iop32x to
> OpenWrt and/or OpenEmbedded, both of which support some
> pretty constrained systems.

This platform is not really too constrained... E.g. on N2100 you have
512 MB RAM, SATA disks and gigabit ethernet. Not that different from
mvebu that Debian currently (?) supports. Maybe with multiplatform they
could support iop32x again.

A.

^ permalink raw reply

* Re: [PATCH v2] gpio: pl061: Fix the issue failed to register the ACPI interrtupion
From: Andy Shevchenko @ 2019-08-16 13:40 UTC (permalink / raw)
  To: Wei Xu
  Cc: open list:GPIO SUBSYSTEM, Linux Kernel Mailing List,
	linux-arm Mailing List, Linus Walleij, Rafael J. Wysocki,
	Len Brown, Mika Westerberg, Linuxarm, shameerali.kolothum.thodi,
	Jonathan Cameron, John Garry, salil.mehta, shiju.jose, jinying,
	zhangyi.ac, liguozhu, tangkunshan, huangdaode
In-Reply-To: <1565946336-20080-1-git-send-email-xuwei5@hisilicon.com>

On Fri, Aug 16, 2019 at 12:07 PM Wei Xu <xuwei5@hisilicon.com> wrote:
>
> Invoke acpi_gpiochip_request_interrupts after the acpi data has been
> attached to the pl061 acpi node to register interruption.
>
> Otherwise it will be failed to register interruption for the ACPI case.
> Because in the gpiochip_add_data_with_key, acpi_gpiochip_add is invoked
> after gpiochip_add_irqchip but at that time the acpi data has not been
> attached yet.

> 2. cat /proc/interrupts in the guest console:
>
>         estuary:/$ cat /proc/interrupts
>                    CPU0
>         2:         3228     GICv3  27 Level     arch_timer
>         4:           15     GICv3  33 Level     uart-pl011
>         42:           0     GICv3  23 Level     arm-pmu
>         IPI0:         0       Rescheduling interrupts
>         IPI1:         0       Function call interrupts
>         IPI2:         0       CPU stop interrupts
>         IPI3:         0       CPU stop (for crash dump) interrupts
>         IPI4:         0       Timer broadcast interrupts
>         IPI5:         0       IRQ work interrupts
>         IPI6:         0       CPU wake-up interrupts
>         Err:          0
>
> But on QEMU v3.0.0 and Linux kernel v5.2.0-rc7, pl061 interruption is
> there as below:
>
>         estuary:/$ cat /proc/interrupts
>                    CPU0
>           2:       2648     GICv3  27 Level     arch_timer
>           4:         12     GICv3  33 Level     uart-pl011
>          42:          0     GICv3  23 Level     arm-pmu
>          43:          0  ARMH0061:00   3 Edge      ACPI:Event
>         IPI0:         0       Rescheduling interrupts
>         IPI1:         0       Function call interrupts
>         IPI2:         0       CPU stop interrupts
>         IPI3:         0       CPU stop (for crash dump) interrupts
>         IPI4:         0       Timer broadcast interrupts
>         IPI5:         0       IRQ work interrupts
>         IPI6:         0       CPU wake-up interrupts
>         Err:          0

In above show only affected line.

> And the whole dmesg log on Linux kernel v5.2.0-rc7 is as below:

NO!
Please, remove this huge noise!

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* [PATCH] pinctrl: intel: remap the pin number to gpio offset for irq enabled pin
From: Chris Chiu @ 2019-08-16  9:38 UTC (permalink / raw)
  To: mika.westerberg, andriy.shevchenko, linus.walleij
  Cc: linux-gpio, linux-kernel, linux

On Asus X571GT, GPIO 297 is configured as an interrupt and serves
for the touchpad. The touchpad will report input events much less
than expected after S3 suspend/resume, which results in extremely
slow cursor movement. However, the number of interrupts observed
from /proc/interrupts increases much more than expected even no
touching touchpad.

This is due to the value of PADCFG0 of PIN 225 for the interrupt
has been changed from 0x80800102 to 0x80100102. The GPIROUTIOXAPIC
is toggled on which results in the spurious interrupts. The PADCFG0
of PIN 225 is expected to be saved during suspend, but the 297 is
saved instead because the gpiochip_line_is_irq() expect the GPIO
offset but what's really passed to it is PIN number. In this case,
the /sys/kernel/debug/pinctrl/INT3450:00/gpio-ranges shows

288: INT3450:00 GPIOS [436 - 459] PINS [216 - 239]

So gpiochip_line_is_irq() returns true for GPIO offset 297, the
suspend routine spuriously saves the content for PIN 297 which
we expect to save for PIN 225.

This commit maps the PIN number to GPIO offset first in the
intel_pinctrl_should_save() to make sure the values for the
specific PINs can be correctly saved and then restored.

Signed-off-by: Chris Chiu <chiu@endlessm.com>

---
 drivers/pinctrl/intel/pinctrl-intel.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index a18d6eefe672..8d6a843bbc7e 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -796,6 +796,29 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
 	return -EINVAL;
 }
 
+/**
+ * intel_pin_to_gpio() - Translate from pin number to GPIO offset
+ * @pctrl: Pinctrl structure
+ * @pin: pin number
+ *
+ * Translate the pin number of pinctrl to GPIO offset
+ */
+static int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin)
+{
+	const struct intel_community *community;
+	const struct intel_padgroup *padgrp;
+
+	community = intel_get_community(pctrl, pin);
+	if (!community)
+		return -EINVAL;
+
+	padgrp = intel_community_get_padgroup(community, pin);
+	if (!padgrp)
+		return -EINVAL;
+
+	return pin - padgrp->base + padgrp->gpio_base;
+}
+
 static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
@@ -1443,7 +1466,8 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
 	 * them alone.
 	 */
 	if (pd->mux_owner || pd->gpio_owner ||
-	    gpiochip_line_is_irq(&pctrl->chip, pin))
+	    gpiochip_line_is_irq(&pctrl->chip,
+				 intel_pin_to_gpio(pctrl, pin)))
 		return true;
 
 	return false;
-- 
2.22.1


^ permalink raw reply related

* [PATCH v2] gpio: pl061: Fix the issue failed to register the ACPI interrtupion
From: Wei Xu @ 2019-08-16  9:05 UTC (permalink / raw)
  To: xuwei5, linux-gpio, linux-kernel, linux-arm-kernel, linus.walleij,
	rjw, lenb, mika.westerberg, andy.shevchenko
  Cc: linuxarm, shameerali.kolothum.thodi, jonathan.cameron, john.garry,
	salil.mehta, shiju.jose, jinying, zhangyi.ac, liguozhu,
	tangkunshan, huangdaode

Invoke acpi_gpiochip_request_interrupts after the acpi data has been
attached to the pl061 acpi node to register interruption.

Otherwise it will be failed to register interruption for the ACPI case.
Because in the gpiochip_add_data_with_key, acpi_gpiochip_add is invoked
after gpiochip_add_irqchip but at that time the acpi data has not been
attached yet.

Tested with below steps on QEMU v4.1.0-rc3 and Linux kernel v5.3-rc4,
and found pl061 interruption is missed in the /proc/interrupts:
1.
qemu-system-aarch64 \
-machine virt,gic-version=3 -cpu cortex-a57 \
-m 1G,maxmem=4G,slots=4 \
-kernel Image -initrd rootfs.cpio.gz \
-net none -nographic  \
-bios QEMU_EFI.fd  \
-append "console=ttyAMA0 acpi=force earlycon=pl011,0x9000000"

2. cat /proc/interrupts in the guest console:

	estuary:/$ cat /proc/interrupts
		   CPU0
	2:         3228     GICv3  27 Level     arch_timer
	4:           15     GICv3  33 Level     uart-pl011
	42:           0     GICv3  23 Level     arm-pmu
	IPI0:         0       Rescheduling interrupts
	IPI1:         0       Function call interrupts
	IPI2:         0       CPU stop interrupts
	IPI3:         0       CPU stop (for crash dump) interrupts
	IPI4:         0       Timer broadcast interrupts
	IPI5:         0       IRQ work interrupts
	IPI6:         0       CPU wake-up interrupts
	Err:          0

But on QEMU v3.0.0 and Linux kernel v5.2.0-rc7, pl061 interruption is
there as below:

	estuary:/$ cat /proc/interrupts
		   CPU0
	  2:       2648     GICv3  27 Level     arch_timer
	  4:         12     GICv3  33 Level     uart-pl011
	 42:          0     GICv3  23 Level     arm-pmu
	 43:          0  ARMH0061:00   3 Edge      ACPI:Event
	IPI0:         0       Rescheduling interrupts
	IPI1:         0       Function call interrupts
	IPI2:         0       CPU stop interrupts
	IPI3:         0       CPU stop (for crash dump) interrupts
	IPI4:         0       Timer broadcast interrupts
	IPI5:         0       IRQ work interrupts
	IPI6:         0       CPU wake-up interrupts
	Err:          0

And the whole dmesg log on Linux kernel v5.2.0-rc7 is as below:

	[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x411fd070]
	[    0.000000] Linux version 5.2.0-rc7 (joyx@Turing-Arch-b) (gcc version 4.9.1 20140505 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.05 - Linaro GCC 4.9-2014.05)) #61 SMP PREEMPT Fri Aug 16 11:54:31 CST 2019
	[    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
	[    0.000000] printk: bootconsole [pl11] enabled
	[    0.000000] efi: Getting EFI parameters from FDT:
	[    0.000000] efi: EFI v2.70 by EDK II
	[    0.000000] efi:  SMBIOS 3.0=0x7f8e0000  MEMATTR=0x7d60f018  ACPI 2.0=0x7c270000  MEMRESERVE=0x7c503018
	[    0.000000] cma: Reserved 32 MiB at 0x000000007a000000
	[    0.000000] ACPI: Early table checksum verification disabled
	[    0.000000] ACPI: RSDP 0x000000007C270000 000024 (v02 BOCHS )
	[    0.000000] ACPI: XSDT 0x000000007C260000 000054 (v01 BOCHS  BXPCFACP 00000001      01000013)
	[    0.000000] ACPI: FACP 0x000000007C220000 00010C (v05 BOCHS  BXPCFACP 00000001 BXPC 00000001)
	[    0.000000] ACPI: DSDT 0x000000007C230000 00482C (v02 BOCHS  BXPCDSDT 00000001 BXPC 00000001)
	[    0.000000] ACPI: APIC 0x000000007C210000 0000A0 (v03 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
	[    0.000000] ACPI: GTDT 0x000000007C200000 000060 (v02 BOCHS  BXPCGTDT 00000001 BXPC 00000001)v
	[    0.000000] ACPI: MCFG 0x000000007C1F0000 00003C (v01 BOCHS  BXPCMCFG 00000001 BXPC 00000001)
	[    0.000000] ACPI: SPCR 0x000000007C1E0000 000050 (v02 BOCHS  BXPCSPCR 00000001 BXPC 00000001)
	[    0.000000] ACPI: SRAT 0x000000007C1D0000 00006A (v03 BOCHS  BXPCSRAT 00000001 BXPC 00000001)
	[    0.000000] ACPI: SPCR: console: pl011,mmio,0x9000000,9600
	[    0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x40000000-0x7fffffff]
	[    0.000000] NUMA: NODE_DATA [mem 0x7fdfb840-0x7fdfcfff]
	[    0.000000] Zone ranges:
	[    0.000000]   DMA32    [mem 0x0000000040000000-0x000000007fffffff]
	[    0.000000]   Normal   empty
	[    0.000000] Movable zone start for each node
	[    0.000000] Early memory node ranges
	[    0.000000]   node   0: [mem 0x0000000040000000-0x000000007c27ffff]
	[    0.000000]   node   0: [mem 0x000000007c280000-0x000000007c4fffff]
	[    0.000000]   node   0: [mem 0x000000007c500000-0x000000007f7dffff]
	[    0.000000]   node   0: [mem 0x000000007f7e0000-0x000000007f86ffff]
	[    0.000000]   node   0: [mem 0x000000007f870000-0x000000007f87ffff]
	[    0.000000]   node   0: [mem 0x000000007f880000-0x000000007f99ffff]
	[    0.000000]   node   0: [mem 0x000000007f9a0000-0x000000007fffffff]
	[    0.000000] Zeroed struct page in unavailable ranges: 416 pages
	[    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000007fffffff]
	[    0.000000] On node 0 totalpages: 262144
	[    0.000000]   DMA32 zone: 4096 pages used for memmap
	[    0.000000]   DMA32 zone: 0 pages reserved
	[    0.000000]   DMA32 zone: 262144 pages, LIFO batch:63
	[    0.000000] psci: probing for conduit method from ACPI.
	[    0.000000] psci: PSCIv0.2 detected in firmware.
	[    0.000000] psci: Using standard PSCI v0.2 function IDs
	[    0.000000] psci: Trusted OS migration not required
	[    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x0 -> Node 0
	[    0.000000] percpu: Embedded 23 pages/cpu s56768 r8192 d29248 u94208
	[    0.000000] pcpu-alloc: s56768 r8192 d29248 u94208 alloc=23*4096
	[    0.000000] pcpu-alloc: [0] 0
	[    0.000000] Detected PIPT I-cache on CPU0
	[    0.000000] CPU features: detected: ARM erratum 832075
	[    0.000000] CPU features: detected: GIC system register CPU interface
	[    0.000000] CPU features: detected: ARM erratum 834220
	[    0.000000] CPU features: detected: EL2 vector hardening
	[    0.000000] ARM_SMCCC_ARCH_WORKAROUND_1 missing from firmware
	[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 258048
	[    0.000000] Policy zone: DMA32
	[    0.000000] Kernel command line: console=ttyAMA0 acpi=force earlycon=pl011,0x9000000 initrd=initrd
	[    0.000000] Memory: 848128K/1048576K available (11132K kernel code, 1766K rwdata, 5924K rodata, 1344K init, 447K bss, 167680K reserved, 32768K cma-reserved)
	[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
	[    0.000000] rcu: Preemptible hierarchical RCU implementation.
	[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=1.
	[    0.000000]  Tasks RCU enabled.
	[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
	[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
	[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
	[    0.000000] GICv3: Distributor has no Range Selector support
	[    0.000000] GICv3: no VLPI support, no direct LPI support
	[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x00000000080a0000
	[    0.000000] random: get_random_bytes called from start_kernel+0x2b4/0x470 with crng_init=0
	[    0.000000] arch_timer: cp15 timer(s) running at 62.50MHz (virt).
	[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1cd42e208c, max_idle_ns: 881590405314 ns
	[    0.000092] sched_clock: 56 bits at 62MHz, resolution 16ns, wraps every 4398046511096ns
	[    0.007507] Console: colour dummy device 80x25
	[    0.009048] ACPI: Core revision 20190509
	[    0.013315] Calibrating delay loop (skipped), value calculated using timer frequency.. 125.00 BogoMIPS (lpj=250000)
	[    0.014388] pid_max: default: 32768 minimum: 301
	[    0.015596] LSM: Security Framework initializing
	[    0.125480] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes)
	[    0.126961] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes)
	[    0.127543] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes)
	[    0.127927] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes)
	[    0.139974] *** VALIDATE proc ***
	[    0.144385] *** VALIDATE cgroup1 ***
	[    0.144602] *** VALIDATE cgroup2 ***
	[    0.156728] ACPI PPTT: No PPTT table found, CPU and cache topology may be inaccurate
	[    0.185506] ASID allocator initialised with 32768 entries
	[    0.193054] rcu: Hierarchical SRCU implementation.
	[    0.204036] Remapping and enabling EFI services.
	[    0.213563] smp: Bringing up secondary CPUs ...
	[    0.213898] smp: Brought up 1 node, 1 CPU
	[    0.214131] SMP: Total of 1 processors activated.
	[    0.214418] CPU features: detected: 32-bit EL0 Support
	[    0.214766] CPU features: detected: CRC32 instructions
	[    0.223253] CPU: All CPU(s) started at EL1
	[    0.223634] alternatives: patching kernel code
	[    0.244639] devtmpfs: initialized
	[    0.256434] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
	[    0.257056] futex hash table entries: 256 (order: 2, 16384 bytes)
	[    0.263282] pinctrl core: initialized pinctrl subsystem
	[    0.276553] SMBIOS 3.0.0 present.
	[    0.276921] DMI: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015
	[    0.284007] NET: Registered protocol family 16
	[    0.286721] audit: initializing netlink subsys (disabled)
	[    0.291045] audit: type=2000 audit(0.268:1): state=initialized audit_enabled=0 res=1
	[    0.295580] cpuidle: using governor menu
	[    0.297330] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
	[    0.304834] DMA: preallocated 256 KiB pool for atomic allocations
	[    0.308014] ACPI: bus type PCI registered
	[    0.308308] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
	[    0.310517] Serial: AMBA PL011 UART driver
	[    0.354362] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
	[    0.354735] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
	[    0.355104] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
	[    0.355445] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
	[    0.382352] cryptd: max_cpu_qlen set to 1000
	[    0.408375] ACPI: Added _OSI(Module Device)
	[    0.408641] ACPI: Added _OSI(Processor Device)
	[    0.408873] ACPI: Added _OSI(3.0 _SCP Extensions)
	[    0.409122] ACPI: Added _OSI(Processor Aggregator Device)
	[    0.409476] ACPI: Added _OSI(Linux-Dell-Video)
	[    0.410058] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
	[    0.410334] ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics)
	[    0.491373] ACPI: 1 ACPI AML tables successfully acquired and loaded
	[    0.506610] ACPI: Interpreter enabled
	[    0.506855] ACPI: Using GIC for interrupt routing
	[    0.507529] ACPI: MCFG table detected, 1 entries
	[    0.562419] ARMH0011:00: ttyAMA0 at MMIO 0x9000000 (irq = 4, base_baud = 0) is a SBSA
	[    0.635348] printk: console [ttyAMA0] enabled
	[    0.671533] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
	[    0.672857] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3]
	[    0.680379] acpi PNP0A08:00: _OSC: platform does not support [LTR]
	[    0.683111] acpi PNP0A08:00: _OSC: OS now controls [PME AER PCIeCapability]
	[    0.688777] acpi PNP0A08:00: ECAM area [mem 0x4010000000-0x401fffffff] reserved by PNP0C02:00
	[    0.689904] acpi PNP0A08:00: ECAM at [mem 0x4010000000-0x401fffffff] for [bus 00-ff]
	[    0.691879] Remapped I/O 0x000000003eff0000 to [io  0x0000-0xffff window]
	[    0.695715] PCI host bridge to bus 0000:00
	[    0.696261] pci_bus 0000:00: root bus resource [mem 0x10000000-0x3efeffff window]
	[    0.697055] pci_bus 0000:00: root bus resource [io  0x0000-0xffff window]
	[    0.697735] pci_bus 0000:00: root bus resource [mem 0x8000000000-0xffffffffff window]
	[    0.698606] pci_bus 0000:00: root bus resource [bus 00-ff]
	[    0.700266] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000
	[    0.706988] ACPI: PCI Interrupt Link [GSI0] (IRQs *35)
	[    0.707965] ACPI: PCI Interrupt Link [GSI1] (IRQs *36)
	[    0.708661] ACPI: PCI Interrupt Link [GSI2] (IRQs *37)
	[    0.709336] ACPI: PCI Interrupt Link [GSI3] (IRQs *38)
	[    0.721505] vgaarb: loaded
	[    0.723261] SCSI subsystem initialized
	[    0.725065] libata version 3.00 loaded.
	[    0.726270] ACPI: bus type USB registered
	[    0.727346] usbcore: registered new interface driver usbfs
	[    0.728223] usbcore: registered new interface driver hub
	[    0.729326] usbcore: registered new device driver usb
	[    0.732056] pps_core: LinuxPPS API ver. 1 registered
	[    0.732580] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
	[    0.733803] PTP clock support registered
	[    0.734781] EDAC MC: Ver: 3.0.0
	[    0.739155] Registered efivars operations
	[    0.752186] FPGA manager framework
	[    0.753453] Advanced Linux Sound Architecture Driver Initialized.
	[    0.767808] clocksource: Switched to clocksource arch_sys_counter
	[    0.769435] VFS: Disk quotas dquot_6.6.0
	[    0.770090] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
	[    0.772939] *** VALIDATE hugetlbfs ***
	[    0.775509] pnp: PnP ACPI init
	[    0.779262] system 00:00: [mem 0x4010000000-0x401fffffff window] could not be reserved
	[    0.780474] system 00:00: Plug and Play ACPI device, IDs PNP0c02 (active)
	[    0.780648] pnp: PnP ACPI: found 1 devices
	[    0.814296] NET: Registered protocol family 2
	[    0.820604] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes)
	[    0.821551] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
	[    0.822567] TCP bind hash table entries: 8192 (order: 5, 131072 bytes)
	[    0.823490] TCP: Hash tables configured (established 8192 bind 8192)
	[    0.826650] UDP hash table entries: 512 (order: 2, 16384 bytes)
	[    0.827508] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
	[    0.829971] NET: Registered protocol family 1
	[    0.846727] RPC: Registered named UNIX socket transport module.
	[    0.847379] RPC: Registered udp transport module.
	[    0.848334] RPC: Registered tcp transport module.
	[    0.848818] RPC: Registered tcp NFSv4.1 backchannel transport module.
	[    0.849786] PCI: CLS 0 bytes, default 64
	[    0.853671] Unpacking initramfs...
	[    6.993882] Freeing initrd memory: 123392K
	[    6.996833] hw perfevents: enabled with armv8_pmuv3_0 PMU driver, 1 counters available
	[    6.997772] kvm [1]: HYP mode not available
	[    7.699500] Initialise system trusted keyrings
	[    7.701698] workingset: timestamp_bits=44 max_order=18 bucket_order=0
	[    7.734096] squashfs: version 4.0 (2009/01/31) Phillip Lougher
	[    7.742467] NFS: Registering the id_resolver key type
	[    7.743404] Key type id_resolver registered
	[    7.744455] Key type id_legacy registered
	[    7.745321] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
	[    7.747602] 9p: Installing v9fs 9p2000 file system support
	[    7.778884] Key type asymmetric registered
	[    7.779383] Asymmetric key parser 'x509' registered
	[    7.780548] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 245)
	[    7.781375] io scheduler mq-deadline registered
	[    7.781899] io scheduler kyber registered
	[    7.809878] pl061_gpio ARMH0061:00: PL061 GPIO chip @0x0000000009030000 registered
	[    7.820983] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
	[    7.822495] ACPI: Power Button [PWRB]
	[    7.829682] EINJ: EINJ table not found.
	[    7.893411] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
	[    7.902202] SuperH (H)SCI(F) driver initialized
	[    7.904102] msm_serial: driver initialized
	[    7.908209] cacheinfo: Unable to detect cache hierarchy for CPU 0
	[    7.940712] loop: module loaded
	[    7.957364] libphy: Fixed MDIO Bus: probed
	[    7.959166] tun: Universal TUN/TAP device driver, 1.6
	[    7.962432] thunder_xcv, ver 1.0
	[    7.962986] thunder_bgx, ver 1.0
	[    7.963542] nicpf, ver 1.0
	[    7.965950] hclge is initializing
	[    7.966402] hns3: Hisilicon Ethernet Network Driver for Hip08 Family - version
	[    7.967095] hns3: Copyright (c) 2017 Huawei Corporation.
	[    7.968228] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
	[    7.968792] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
	[    7.969591] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.6.0-k
	[    7.970258] igb: Copyright (c) 2007-2014 Intel Corporation.
	[    7.971023] igbvf: Intel(R) Gigabit Virtual Function Network Driver - version 2.4.0-k
	[    7.971977] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
	[    7.973720] sky2: driver version 1.30
	[    7.976724] VFIO - User Level meta-driver version: 0.3
	[    7.988959] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
	[    7.989976] ehci-pci: EHCI PCI platform driver
	[    7.991065] ehci-platform: EHCI generic platform driver
	[    7.992716] ehci-orion: EHCI orion driver
	[    7.993799] ehci-exynos: EHCI EXYNOS driver
	[    7.994893] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
	[    7.995615] ohci-pci: OHCI PCI platform driver
	[    7.996497] ohci-platform: OHCI generic platform driver
	[    7.997352] ohci-exynos: OHCI EXYNOS driver
	[    7.999395] usbcore: registered new interface driver usb-storage
	[    8.013108] rtc-efi rtc-efi: registered as rtc0
	[    8.016099] i2c /dev entries driver
	[    8.031422] sdhci: Secure Digital Host Controller Interface driver
	[    8.032163] sdhci: Copyright(c) Pierre Ossman
	[    8.034139] Synopsys Designware Multimedia Card Interface Driver
	[    8.037333] sdhci-pltfm: SDHCI platform and OF driver helper
	[    8.042220] ledtrig-cpu: registered to indicate activity on CPUs
	[    8.049014] usbcore: registered new interface driver usbhid
	[    8.049565] usbhid: USB HID core driver
	[    8.062947] NET: Registered protocol family 17
	[    8.065201] 9pnet: Installing 9P2000 support
	[    8.065961] Key type dns_resolver registered
	[    8.069421] registered taskstats version 1
	[    8.069864] Loading compiled-in X.509 certificates
	[    8.075662] rtc-efi rtc-efi: setting system clock to 2019-08-16T07:48:26 UTC (1565941706)
	[    8.079525] ALSA device list:
	[    8.080167]   No soundcards found.
	[    8.478229] Freeing unused kernel memory: 1344K
	[    8.480677] Run /init as init process
	[    9.767007] random: sshd: uninitialized urandom read (32 bytes read)
	estuary:/$

Fixes: 04ce935c6b2a ("gpio: pl061: Pass irqchip when adding gpiochip")
Signed-off-by: Wei Xu <xuwei5@hisilicon.com>
---

v1- > v2:
* rebased on https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/log/?h=devel
* attached the log based on QEMU v3.0.0 and Linux kernel v5.2.0-rc7
---
 drivers/gpio/gpio-pl061.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 722ce5c..e1a434e 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -8,6 +8,7 @@
  *
  * Data sheet: ARM DDI 0190B, September 2000
  */
+#include <linux/acpi.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -24,6 +25,9 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/pm.h>
 
+#include "gpiolib.h"
+#include "gpiolib-acpi.h"
+
 #define GPIODIR 0x400
 #define GPIOIS  0x404
 #define GPIOIBE 0x408
@@ -345,6 +349,9 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
 	if (ret)
 		return ret;
 
+	if (has_acpi_companion(dev))
+		acpi_gpiochip_request_interrupts(&pl061->gc);
+
 	amba_set_drvdata(adev, pl061);
 	dev_info(dev, "PL061 GPIO chip registered\n");
 
-- 
2.8.1


^ permalink raw reply related

* [PATCH v2] gpio: pl061: Fix the issue failed to register the ACPI interrtupion
From: Wei Xu @ 2019-08-16  8:58 UTC (permalink / raw)
  To: xuwei5, linux-gpio

Invoke acpi_gpiochip_request_interrupts after the acpi data has been
attached to the pl061 acpi node to register interruption.

Otherwise it will be failed to register interruption for the ACPI case.
Because in the gpiochip_add_data_with_key, acpi_gpiochip_add is invoked
after gpiochip_add_irqchip but at that time the acpi data has not been
attached yet.

Tested with below steps on QEMU v4.1.0-rc3 and Linux kernel v5.3-rc4,
and found pl061 interruption is missed in the /proc/interrupts:
1.
qemu-system-aarch64 \
-machine virt,gic-version=3 -cpu cortex-a57 \
-m 1G,maxmem=4G,slots=4 \
-kernel Image -initrd rootfs.cpio.gz \
-net none -nographic  \
-bios QEMU_EFI.fd  \
-append "console=ttyAMA0 acpi=force earlycon=pl011,0x9000000"

2. cat /proc/interrupts in the guest console:

	estuary:/$ cat /proc/interrupts
		   CPU0
	2:         3228     GICv3  27 Level     arch_timer
	4:           15     GICv3  33 Level     uart-pl011
	42:           0     GICv3  23 Level     arm-pmu
	IPI0:         0       Rescheduling interrupts
	IPI1:         0       Function call interrupts
	IPI2:         0       CPU stop interrupts
	IPI3:         0       CPU stop (for crash dump) interrupts
	IPI4:         0       Timer broadcast interrupts
	IPI5:         0       IRQ work interrupts
	IPI6:         0       CPU wake-up interrupts
	Err:          0

But on QEMU v3.0.0 and Linux kernel v5.2.0-rc7, pl061 interruption is
there as below:

	estuary:/$ cat /proc/interrupts
		   CPU0
	  2:       2648     GICv3  27 Level     arch_timer
	  4:         12     GICv3  33 Level     uart-pl011
	 42:          0     GICv3  23 Level     arm-pmu
	 43:          0  ARMH0061:00   3 Edge      ACPI:Event
	IPI0:         0       Rescheduling interrupts
	IPI1:         0       Function call interrupts
	IPI2:         0       CPU stop interrupts
	IPI3:         0       CPU stop (for crash dump) interrupts
	IPI4:         0       Timer broadcast interrupts
	IPI5:         0       IRQ work interrupts
	IPI6:         0       CPU wake-up interrupts
	Err:          0

And the whole dmesg log on Linux kernel v5.2.0-rc7 is as below:

	[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x411fd070]
	[    0.000000] Linux version 5.2.0-rc7 (joyx@Turing-Arch-b) (gcc version 4.9.1 20140505 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.05 - Linaro GCC 4.9-2014.05)) #61 SMP PREEMPT Fri Aug 16 11:54:31 CST 2019
	[    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
	[    0.000000] printk: bootconsole [pl11] enabled
	[    0.000000] efi: Getting EFI parameters from FDT:
	[    0.000000] efi: EFI v2.70 by EDK II
	[    0.000000] efi:  SMBIOS 3.0=0x7f8e0000  MEMATTR=0x7d60f018  ACPI 2.0=0x7c270000  MEMRESERVE=0x7c503018
	[    0.000000] cma: Reserved 32 MiB at 0x000000007a000000
	[    0.000000] ACPI: Early table checksum verification disabled
	[    0.000000] ACPI: RSDP 0x000000007C270000 000024 (v02 BOCHS )
	[    0.000000] ACPI: XSDT 0x000000007C260000 000054 (v01 BOCHS  BXPCFACP 00000001      01000013)
	[    0.000000] ACPI: FACP 0x000000007C220000 00010C (v05 BOCHS  BXPCFACP 00000001 BXPC 00000001)
	[    0.000000] ACPI: DSDT 0x000000007C230000 00482C (v02 BOCHS  BXPCDSDT 00000001 BXPC 00000001)
	[    0.000000] ACPI: APIC 0x000000007C210000 0000A0 (v03 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
	[    0.000000] ACPI: GTDT 0x000000007C200000 000060 (v02 BOCHS  BXPCGTDT 00000001 BXPC 00000001)v
	[    0.000000] ACPI: MCFG 0x000000007C1F0000 00003C (v01 BOCHS  BXPCMCFG 00000001 BXPC 00000001)
	[    0.000000] ACPI: SPCR 0x000000007C1E0000 000050 (v02 BOCHS  BXPCSPCR 00000001 BXPC 00000001)
	[    0.000000] ACPI: SRAT 0x000000007C1D0000 00006A (v03 BOCHS  BXPCSRAT 00000001 BXPC 00000001)
	[    0.000000] ACPI: SPCR: console: pl011,mmio,0x9000000,9600
	[    0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x40000000-0x7fffffff]
	[    0.000000] NUMA: NODE_DATA [mem 0x7fdfb840-0x7fdfcfff]
	[    0.000000] Zone ranges:
	[    0.000000]   DMA32    [mem 0x0000000040000000-0x000000007fffffff]
	[    0.000000]   Normal   empty
	[    0.000000] Movable zone start for each node
	[    0.000000] Early memory node ranges
	[    0.000000]   node   0: [mem 0x0000000040000000-0x000000007c27ffff]
	[    0.000000]   node   0: [mem 0x000000007c280000-0x000000007c4fffff]
	[    0.000000]   node   0: [mem 0x000000007c500000-0x000000007f7dffff]
	[    0.000000]   node   0: [mem 0x000000007f7e0000-0x000000007f86ffff]
	[    0.000000]   node   0: [mem 0x000000007f870000-0x000000007f87ffff]
	[    0.000000]   node   0: [mem 0x000000007f880000-0x000000007f99ffff]
	[    0.000000]   node   0: [mem 0x000000007f9a0000-0x000000007fffffff]
	[    0.000000] Zeroed struct page in unavailable ranges: 416 pages
	[    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000007fffffff]
	[    0.000000] On node 0 totalpages: 262144
	[    0.000000]   DMA32 zone: 4096 pages used for memmap
	[    0.000000]   DMA32 zone: 0 pages reserved
	[    0.000000]   DMA32 zone: 262144 pages, LIFO batch:63
	[    0.000000] psci: probing for conduit method from ACPI.
	[    0.000000] psci: PSCIv0.2 detected in firmware.
	[    0.000000] psci: Using standard PSCI v0.2 function IDs
	[    0.000000] psci: Trusted OS migration not required
	[    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x0 -> Node 0
	[    0.000000] percpu: Embedded 23 pages/cpu s56768 r8192 d29248 u94208
	[    0.000000] pcpu-alloc: s56768 r8192 d29248 u94208 alloc=23*4096
	[    0.000000] pcpu-alloc: [0] 0
	[    0.000000] Detected PIPT I-cache on CPU0
	[    0.000000] CPU features: detected: ARM erratum 832075
	[    0.000000] CPU features: detected: GIC system register CPU interface
	[    0.000000] CPU features: detected: ARM erratum 834220
	[    0.000000] CPU features: detected: EL2 vector hardening
	[    0.000000] ARM_SMCCC_ARCH_WORKAROUND_1 missing from firmware
	[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 258048
	[    0.000000] Policy zone: DMA32
	[    0.000000] Kernel command line: console=ttyAMA0 acpi=force earlycon=pl011,0x9000000 initrd=initrd
	[    0.000000] Memory: 848128K/1048576K available (11132K kernel code, 1766K rwdata, 5924K rodata, 1344K init, 447K bss, 167680K reserved, 32768K cma-reserved)
	[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
	[    0.000000] rcu: Preemptible hierarchical RCU implementation.
	[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=1.
	[    0.000000]  Tasks RCU enabled.
	[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
	[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
	[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
	[    0.000000] GICv3: Distributor has no Range Selector support
	[    0.000000] GICv3: no VLPI support, no direct LPI support
	[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x00000000080a0000
	[    0.000000] random: get_random_bytes called from start_kernel+0x2b4/0x470 with crng_init=0
	[    0.000000] arch_timer: cp15 timer(s) running at 62.50MHz (virt).
	[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1cd42e208c, max_idle_ns: 881590405314 ns
	[    0.000092] sched_clock: 56 bits at 62MHz, resolution 16ns, wraps every 4398046511096ns
	[    0.007507] Console: colour dummy device 80x25
	[    0.009048] ACPI: Core revision 20190509
	[    0.013315] Calibrating delay loop (skipped), value calculated using timer frequency.. 125.00 BogoMIPS (lpj=250000)
	[    0.014388] pid_max: default: 32768 minimum: 301
	[    0.015596] LSM: Security Framework initializing
	[    0.125480] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes)
	[    0.126961] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes)
	[    0.127543] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes)
	[    0.127927] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes)
	[    0.139974] *** VALIDATE proc ***
	[    0.144385] *** VALIDATE cgroup1 ***
	[    0.144602] *** VALIDATE cgroup2 ***
	[    0.156728] ACPI PPTT: No PPTT table found, CPU and cache topology may be inaccurate
	[    0.185506] ASID allocator initialised with 32768 entries
	[    0.193054] rcu: Hierarchical SRCU implementation.
	[    0.204036] Remapping and enabling EFI services.
	[    0.213563] smp: Bringing up secondary CPUs ...
	[    0.213898] smp: Brought up 1 node, 1 CPU
	[    0.214131] SMP: Total of 1 processors activated.
	[    0.214418] CPU features: detected: 32-bit EL0 Support
	[    0.214766] CPU features: detected: CRC32 instructions
	[    0.223253] CPU: All CPU(s) started at EL1
	[    0.223634] alternatives: patching kernel code
	[    0.244639] devtmpfs: initialized
	[    0.256434] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
	[    0.257056] futex hash table entries: 256 (order: 2, 16384 bytes)
	[    0.263282] pinctrl core: initialized pinctrl subsystem
	[    0.276553] SMBIOS 3.0.0 present.
	[    0.276921] DMI: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015
	[    0.284007] NET: Registered protocol family 16
	[    0.286721] audit: initializing netlink subsys (disabled)
	[    0.291045] audit: type=2000 audit(0.268:1): state=initialized audit_enabled=0 res=1
	[    0.295580] cpuidle: using governor menu
	[    0.297330] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
	[    0.304834] DMA: preallocated 256 KiB pool for atomic allocations
	[    0.308014] ACPI: bus type PCI registered
	[    0.308308] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
	[    0.310517] Serial: AMBA PL011 UART driver
	[    0.354362] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
	[    0.354735] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
	[    0.355104] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
	[    0.355445] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
	[    0.382352] cryptd: max_cpu_qlen set to 1000
	[    0.408375] ACPI: Added _OSI(Module Device)
	[    0.408641] ACPI: Added _OSI(Processor Device)
	[    0.408873] ACPI: Added _OSI(3.0 _SCP Extensions)
	[    0.409122] ACPI: Added _OSI(Processor Aggregator Device)
	[    0.409476] ACPI: Added _OSI(Linux-Dell-Video)
	[    0.410058] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
	[    0.410334] ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics)
	[    0.491373] ACPI: 1 ACPI AML tables successfully acquired and loaded
	[    0.506610] ACPI: Interpreter enabled
	[    0.506855] ACPI: Using GIC for interrupt routing
	[    0.507529] ACPI: MCFG table detected, 1 entries
	[    0.562419] ARMH0011:00: ttyAMA0 at MMIO 0x9000000 (irq = 4, base_baud = 0) is a SBSA
	[    0.635348] printk: console [ttyAMA0] enabled
	[    0.671533] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
	[    0.672857] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3]
	[    0.680379] acpi PNP0A08:00: _OSC: platform does not support [LTR]
	[    0.683111] acpi PNP0A08:00: _OSC: OS now controls [PME AER PCIeCapability]
	[    0.688777] acpi PNP0A08:00: ECAM area [mem 0x4010000000-0x401fffffff] reserved by PNP0C02:00
	[    0.689904] acpi PNP0A08:00: ECAM at [mem 0x4010000000-0x401fffffff] for [bus 00-ff]
	[    0.691879] Remapped I/O 0x000000003eff0000 to [io  0x0000-0xffff window]
	[    0.695715] PCI host bridge to bus 0000:00
	[    0.696261] pci_bus 0000:00: root bus resource [mem 0x10000000-0x3efeffff window]
	[    0.697055] pci_bus 0000:00: root bus resource [io  0x0000-0xffff window]
	[    0.697735] pci_bus 0000:00: root bus resource [mem 0x8000000000-0xffffffffff window]
	[    0.698606] pci_bus 0000:00: root bus resource [bus 00-ff]
	[    0.700266] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000
	[    0.706988] ACPI: PCI Interrupt Link [GSI0] (IRQs *35)
	[    0.707965] ACPI: PCI Interrupt Link [GSI1] (IRQs *36)
	[    0.708661] ACPI: PCI Interrupt Link [GSI2] (IRQs *37)
	[    0.709336] ACPI: PCI Interrupt Link [GSI3] (IRQs *38)
	[    0.721505] vgaarb: loaded
	[    0.723261] SCSI subsystem initialized
	[    0.725065] libata version 3.00 loaded.
	[    0.726270] ACPI: bus type USB registered
	[    0.727346] usbcore: registered new interface driver usbfs
	[    0.728223] usbcore: registered new interface driver hub
	[    0.729326] usbcore: registered new device driver usb
	[    0.732056] pps_core: LinuxPPS API ver. 1 registered
	[    0.732580] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
	[    0.733803] PTP clock support registered
	[    0.734781] EDAC MC: Ver: 3.0.0
	[    0.739155] Registered efivars operations
	[    0.752186] FPGA manager framework
	[    0.753453] Advanced Linux Sound Architecture Driver Initialized.
	[    0.767808] clocksource: Switched to clocksource arch_sys_counter
	[    0.769435] VFS: Disk quotas dquot_6.6.0
	[    0.770090] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
	[    0.772939] *** VALIDATE hugetlbfs ***
	[    0.775509] pnp: PnP ACPI init
	[    0.779262] system 00:00: [mem 0x4010000000-0x401fffffff window] could not be reserved
	[    0.780474] system 00:00: Plug and Play ACPI device, IDs PNP0c02 (active)
	[    0.780648] pnp: PnP ACPI: found 1 devices
	[    0.814296] NET: Registered protocol family 2
	[    0.820604] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes)
	[    0.821551] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
	[    0.822567] TCP bind hash table entries: 8192 (order: 5, 131072 bytes)
	[    0.823490] TCP: Hash tables configured (established 8192 bind 8192)
	[    0.826650] UDP hash table entries: 512 (order: 2, 16384 bytes)
	[    0.827508] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
	[    0.829971] NET: Registered protocol family 1
	[    0.846727] RPC: Registered named UNIX socket transport module.
	[    0.847379] RPC: Registered udp transport module.
	[    0.848334] RPC: Registered tcp transport module.
	[    0.848818] RPC: Registered tcp NFSv4.1 backchannel transport module.
	[    0.849786] PCI: CLS 0 bytes, default 64
	[    0.853671] Unpacking initramfs...
	[    6.993882] Freeing initrd memory: 123392K
	[    6.996833] hw perfevents: enabled with armv8_pmuv3_0 PMU driver, 1 counters available
	[    6.997772] kvm [1]: HYP mode not available
	[    7.699500] Initialise system trusted keyrings
	[    7.701698] workingset: timestamp_bits=44 max_order=18 bucket_order=0
	[    7.734096] squashfs: version 4.0 (2009/01/31) Phillip Lougher
	[    7.742467] NFS: Registering the id_resolver key type
	[    7.743404] Key type id_resolver registered
	[    7.744455] Key type id_legacy registered
	[    7.745321] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
	[    7.747602] 9p: Installing v9fs 9p2000 file system support
	[    7.778884] Key type asymmetric registered
	[    7.779383] Asymmetric key parser 'x509' registered
	[    7.780548] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 245)
	[    7.781375] io scheduler mq-deadline registered
	[    7.781899] io scheduler kyber registered
	[    7.809878] pl061_gpio ARMH0061:00: PL061 GPIO chip @0x0000000009030000 registered
	[    7.820983] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
	[    7.822495] ACPI: Power Button [PWRB]
	[    7.829682] EINJ: EINJ table not found.
	[    7.893411] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
	[    7.902202] SuperH (H)SCI(F) driver initialized
	[    7.904102] msm_serial: driver initialized
	[    7.908209] cacheinfo: Unable to detect cache hierarchy for CPU 0
	[    7.940712] loop: module loaded
	[    7.957364] libphy: Fixed MDIO Bus: probed
	[    7.959166] tun: Universal TUN/TAP device driver, 1.6
	[    7.962432] thunder_xcv, ver 1.0
	[    7.962986] thunder_bgx, ver 1.0
	[    7.963542] nicpf, ver 1.0
	[    7.965950] hclge is initializing
	[    7.966402] hns3: Hisilicon Ethernet Network Driver for Hip08 Family - version
	[    7.967095] hns3: Copyright (c) 2017 Huawei Corporation.
	[    7.968228] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
	[    7.968792] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
	[    7.969591] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.6.0-k
	[    7.970258] igb: Copyright (c) 2007-2014 Intel Corporation.
	[    7.971023] igbvf: Intel(R) Gigabit Virtual Function Network Driver - version 2.4.0-k
	[    7.971977] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
	[    7.973720] sky2: driver version 1.30
	[    7.976724] VFIO - User Level meta-driver version: 0.3
	[    7.988959] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
	[    7.989976] ehci-pci: EHCI PCI platform driver
	[    7.991065] ehci-platform: EHCI generic platform driver
	[    7.992716] ehci-orion: EHCI orion driver
	[    7.993799] ehci-exynos: EHCI EXYNOS driver
	[    7.994893] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
	[    7.995615] ohci-pci: OHCI PCI platform driver
	[    7.996497] ohci-platform: OHCI generic platform driver
	[    7.997352] ohci-exynos: OHCI EXYNOS driver
	[    7.999395] usbcore: registered new interface driver usb-storage
	[    8.013108] rtc-efi rtc-efi: registered as rtc0
	[    8.016099] i2c /dev entries driver
	[    8.031422] sdhci: Secure Digital Host Controller Interface driver
	[    8.032163] sdhci: Copyright(c) Pierre Ossman
	[    8.034139] Synopsys Designware Multimedia Card Interface Driver
	[    8.037333] sdhci-pltfm: SDHCI platform and OF driver helper
	[    8.042220] ledtrig-cpu: registered to indicate activity on CPUs
	[    8.049014] usbcore: registered new interface driver usbhid
	[    8.049565] usbhid: USB HID core driver
	[    8.062947] NET: Registered protocol family 17
	[    8.065201] 9pnet: Installing 9P2000 support
	[    8.065961] Key type dns_resolver registered
	[    8.069421] registered taskstats version 1
	[    8.069864] Loading compiled-in X.509 certificates
	[    8.075662] rtc-efi rtc-efi: setting system clock to 2019-08-16T07:48:26 UTC (1565941706)
	[    8.079525] ALSA device list:
	[    8.080167]   No soundcards found.
	[    8.478229] Freeing unused kernel memory: 1344K
	[    8.480677] Run /init as init process
	[    9.767007] random: sshd: uninitialized urandom read (32 bytes read)
	estuary:/$

Fixes: 04ce935c6b2a ("gpio: pl061: Pass irqchip when adding gpiochip")
Signed-off-by: Wei Xu <xuwei5@hisilicon.com>
---

v1- > v2:
* rebased on https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/log/?h=devel
* attached the log based on QEMU v3.0.0 and Linux kernel v5.2.0-rc7
---
 drivers/gpio/gpio-pl061.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 722ce5c..e1a434e 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -8,6 +8,7 @@
  *
  * Data sheet: ARM DDI 0190B, September 2000
  */
+#include <linux/acpi.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -24,6 +25,9 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/pm.h>
 
+#include "gpiolib.h"
+#include "gpiolib-acpi.h"
+
 #define GPIODIR 0x400
 #define GPIOIS  0x404
 #define GPIOIBE 0x408
@@ -345,6 +349,9 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
 	if (ret)
 		return ret;
 
+	if (has_acpi_companion(dev))
+		acpi_gpiochip_request_interrupts(&pl061->gc);
+
 	amba_set_drvdata(adev, pl061);
 	dev_info(dev, "PL061 GPIO chip registered\n");
 
-- 
2.8.1


^ permalink raw reply related

* Re: [PATCH] gpio: pl061: Fix the issue failed to register the ACPI interruption
From: Wei Xu @ 2019-08-16  8:41 UTC (permalink / raw)
  To: Linus Walleij
  Cc: open list:GPIO SUBSYSTEM, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, Linuxarm,
	Shameerali Kolothum Thodi, Jonathan Cameron, John Garry,
	Salil Mehta, Shiju Jose, jinying, Zhangyi ac, Liguozhu (Kenneth),
	Tangkunshan, huangdaode
In-Reply-To: <CACRpkdbi21mV5quTmur6egb6FJMFrD-Lg1EUKtk+HejyWjzmUA@mail.gmail.com>

Hi Linus,

On 2019/8/14 17:04, Linus Walleij wrote:
> Hi Wei,
>
> thanks for your patch!
>
> This doesn't apply for my "devel" branch, can you rebase
> on this:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/log/?h=devel
>
> We have moved some ACPI headers around recently.

Thanks to review!
I just sent out the v2 based on that.

> On Mon, Aug 12, 2019 at 1:28 PM Wei Xu <xuwei5@hisilicon.com> wrote:
>
>> Invoke acpi_gpiochip_request_interrupts after the acpi data has been
>> attached to the pl061 acpi node to register interruption.
> Makes sense.
>
>> Fixes: 04ce935c6b2a ("gpio: pl061: Pass irqchip when adding gpiochip")
> I doubt this is a regression since I haven't seen anyone use this
> gpiochip with ACPI before.
>
> Please rename the patch "gpio: pl061: Add ACPI support" unless
> you can convince me it worked without changes before.

In the v2, I attached the log on QEMU v3.0.0 and Linux kernel v5.2.0-rc7 
and
the pl061 driver can register ACPI interruption.
Based on that, I did not rename the patch but I am OK to rename it if 
you have
any doubt.

> Please include some ACPI people on review of this. From
> MAINTAINERS:
> ACPI
> M:      "Rafael J. Wysocki" <rjw@rjwysocki.net>
> M:      Len Brown <lenb@kernel.org>
> L:      linux-acpi@vger.kernel.org
>
> I would also include Andy Shevchenko and Mika Westerberg for
> the GPIO aspects.
Copied to all of them in the v2.
Thanks!

Best Regards,
Wei

> Thanks!
> Linus Walleij
>
> .
>



^ permalink raw reply

* Re: [PATCH] pinctrl: rza1: Add of_node_put() before return
From: Geert Uytterhoeven @ 2019-08-16  7:21 UTC (permalink / raw)
  To: Nishka Dasgupta
  Cc: Geert Uytterhoeven, Linus Walleij, Linux-Renesas,
	open list:GPIO SUBSYSTEM
In-Reply-To: <20190815060503.2853-1-nishkadg.linux@gmail.com>

CC Jacopo, Chris

On Thu, Aug 15, 2019 at 8:05 AM Nishka Dasgupta
<nishkadg.linux@gmail.com> wrote:
> Each iteration of for_each_child_of_node puts the previous node, but in
> the case of a return from the middle of the loop, there is no put, thus
> causing a memory leak. Hence add an of_node_put before the return in
> three places.
> Issue found with Coccinelle.
>
> Signed-off-by: Nishka Dasgupta <nishkadg.linux@gmail.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in sh-pfc-for-v5.4.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v2] serial: mctrl_gpio: Support all GPIO suffixes (gpios vs gpio)
From: Geert Uytterhoeven @ 2019-08-16  7:16 UTC (permalink / raw)
  To: Stefan Roese
  Cc: open list:SERIAL DRIVERS, open list:GPIO SUBSYSTEM, Pavel Machek,
	Linus Walleij, Greg Kroah-Hartman, Mika Westerberg
In-Reply-To: <20190815085341.28088-1-sr@denx.de>

CC Mika, who reported the initial issue

On Thu, Aug 15, 2019 at 10:53 AM Stefan Roese <sr@denx.de> wrote:
>
> This patch fixes a backward compatibility issue, when boards use the
> old style GPIO suffix "-gpio" instead of the new "-gpios". This
> potential problem has been introduced by commit d99482673f95 ("serial:
> mctrl_gpio: Check if GPIO property exisits before requesting it").
>
> This patch now fixes this issue by using gpiod_count() which iterates
> over all supported GPIO suffixes (thanks to Linus for suggesting this).
>
> With this change, the local string is not needed any more. This way
> we can remove the allocation in the loop.
>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Pavel Machek <pavel@denx.de>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> v2
> - Use gpiod_count() to check if the GPIO exists (Linus)
> - Remove the now unnecessary malloc in the loop (kasprintf)
>
>  drivers/tty/serial/serial_mctrl_gpio.c | 13 +++----------
>  1 file changed, 3 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c
> index 2b400189be91..ce73b142c66b 100644
> --- a/drivers/tty/serial/serial_mctrl_gpio.c
> +++ b/drivers/tty/serial/serial_mctrl_gpio.c
> @@ -117,18 +117,11 @@ struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)
>
>         for (i = 0; i < UART_GPIO_MAX; i++) {
>                 enum gpiod_flags flags;
> -               char *gpio_str;
> -               bool present;
> +               int count;
>
>                 /* Check if GPIO property exists and continue if not */
> -               gpio_str = kasprintf(GFP_KERNEL, "%s-gpios",
> -                                    mctrl_gpios_desc[i].name);
> -               if (!gpio_str)
> -                       continue;
> -
> -               present = device_property_present(dev, gpio_str);
> -               kfree(gpio_str);
> -               if (!present)
> +               count = gpiod_count(dev, mctrl_gpios_desc[i].name);
> +               if (count <= 0)
>                         continue;
>
>                 if (mctrl_gpios_desc[i].dir_out)

Seems like both device_property_present() and gpiod_count()
eventually call into acpi_data_get_property().

However, given
commit 6fe9da42f1d98fdb4be1598e230aca97e66cf35d
Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Date:   Tue May 23 20:03:20 2017 +0300

    gpio: acpi: Synchronize acpi_find_gpio() and acpi_gpio_count()

    If we pass connection ID to the both functions and at the same time
    acpi_can_fallback_to_crs() returns false we will get different results,
    i.e. the number of GPIO resources returned by acpi_gpio_count() might be
    not correct.

    Fix this by calling acpi_can_fallback_to_crs() in acpi_gpio_count()
    before trying to fallback.

acpi_find_gpio() and acpi_gpio_count() are supposed to use the exact
same logic, so this patch is not gonna work as intended?!?

Note that I still find it strange that acpi_find_gpio() falls back to
unnamed gpios if con_id != NULL, causing the problem in the first place.
This is gonna bite us again later...

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 1/6 v2] gpio: Add support for hierarchical IRQ domains
From: Brian Masney @ 2019-08-16  1:10 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-gpio, Bartosz Golaszewski, Thomas Gleixner, Marc Zyngier,
	Lina Iyer, Jon Hunter, Sowjanya Komatineni, Bitan Biswas,
	linux-tegra, David Daney, Masahiro Yamada, Thierry Reding
In-Reply-To: <20190808123242.5359-1-linus.walleij@linaro.org>

Hi Linus,

On Thu, Aug 08, 2019 at 02:32:37PM +0200, Linus Walleij wrote:
> Hierarchical IRQ domains can be used to stack different IRQ
> controllers on top of each other.
> 
> Bring hierarchical IRQ domains into the GPIOLIB core with the
> following basic idea:
> 
> Drivers that need their interrupts handled hierarchically
> specify a callback to translate the child hardware IRQ and
> IRQ type for each GPIO offset to a parent hardware IRQ and
> parent hardware IRQ type.
> 
> Users have to pass the callback, fwnode, and parent irqdomain
> before calling gpiochip_irqchip_add().
> 
> We use the new method of just filling in the struct
> gpio_irq_chip before adding the gpiochip for all hierarchical
> irqchips of this type.
> 
> The code path for device tree is pretty straight-forward,
> while the code path for old boardfiles or anything else will
> be more convoluted requireing upfront allocation of the
> interrupts when adding the chip.
> 
> One specific use-case where this can be useful is if a power
> management controller has top-level controls for wakeup
> interrupts. In such cases, the power management controller can
> be a parent to other interrupt controllers and program
> additional registers when an IRQ has its wake capability
> enabled or disabled.
> 
> The hierarchical irqchip helper code will only be available
> when IRQ_DOMAIN_HIERARCHY is selected to GPIO chips using
> this should select or depend on that symbol. When using
> hierarchical IRQs, the parent interrupt controller must
> also be hierarchical all the way up to the top interrupt
> controller wireing directly into the CPU, so on systems
> that do not have this we can get rid of all the extra
> code for supporting hierarchical irqs.
> 
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Lina Iyer <ilina@codeaurora.org>
> Cc: Jon Hunter <jonathanh@nvidia.com>
> Cc: Sowjanya Komatineni <skomatineni@nvidia.com>
> Cc: Bitan Biswas <bbiswas@nvidia.com>
> Cc: linux-tegra@vger.kernel.org
> Cc: David Daney <david.daney@cavium.com>
> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
> Cc: Brian Masney <masneyb@onstation.org>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> Signed-off-by: Brian Masney <masneyb@onstation.org>
> Co-developed-by: Brian Masney <masneyb@onstation.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---

[ snip ]


> @@ -1827,10 +2099,23 @@ EXPORT_SYMBOL_GPL(gpiochip_irq_domain_deactivate);
>  
>  static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset)

   ^^^^^^

I started to convert ssbi-gpio over to this and pm8xxx_gpio_to_irq() has
this little snippet that's different from spmi-gpio:

	[ fwspec mapping code ]

	/*
	 * Cache the IRQ since pm8xxx_gpio_get() needs this to get determine the
	 * line level.
	 */
	pin->irq = ret;

Here's the relevant code in pm8xxx_gpio_get():

	if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) {
		ret = pin->output_value;
	} else if (pin->irq >= 0) {
		ret = irq_get_irqchip_state(pin->irq, IRQCHIP_STATE_LINE_LEVEL, &state);
		...
	}

What do you think about using EXPORT_SYMBOL_GPL() for gpiochip_to_irq() so
that we can call it in pm8xxx_gpio_to_irq()? Or do you have any other
suggestions for how we can get rid of that IRQ cache?

I don't see any other issues for ssbi-gpio.

Brian

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox