Devicetree
 help / color / mirror / Atom feed
* [PATCH V3 2/6] soc/tegra: Move Tegra flowctrl driver
From: Jon Hunter @ 2017-03-28 12:42 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mark Rutland, devicetree, Stephen Warren, Russell King,
	Jon Hunter, Rob Herring, linux-tegra, linux-arm-kernel
In-Reply-To: <1490704978-22906-1-git-send-email-jonathanh@nvidia.com>

The flowctrl driver is required for both ARM and ARM64 Tegra devices
and in order to enable support for it for ARM64, move the Tegra flowctrl
driver into drivers/soc/tegra.

By moving the flowctrl driver, tegra_flowctrl_init() is now called by
via an early initcall and to prevent this function from attempting to
mapping IO space for a non-Tegra device, a test for 'soc_is_tegra()'
is also added.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 arch/arm/mach-tegra/Makefile          |   1 -
 arch/arm/mach-tegra/cpuidle-tegra20.c |   3 +-
 arch/arm/mach-tegra/flowctrl.c        | 179 --------------------------------
 arch/arm/mach-tegra/flowctrl.h        |  66 ------------
 arch/arm/mach-tegra/platsmp.c         |   2 +-
 arch/arm/mach-tegra/pm.c              |   2 +-
 arch/arm/mach-tegra/reset-handler.S   |   2 +-
 arch/arm/mach-tegra/sleep-tegra20.S   |   3 +-
 arch/arm/mach-tegra/sleep-tegra30.S   |   2 +-
 arch/arm/mach-tegra/tegra.c           |   2 -
 drivers/soc/tegra/Kconfig             |   7 ++
 drivers/soc/tegra/Makefile            |   1 +
 drivers/soc/tegra/flowctrl.c          | 187 ++++++++++++++++++++++++++++++++++
 include/soc/tegra/flowctrl.h          |  82 +++++++++++++++
 14 files changed, 285 insertions(+), 254 deletions(-)
 delete mode 100644 arch/arm/mach-tegra/flowctrl.c
 delete mode 100644 arch/arm/mach-tegra/flowctrl.h
 create mode 100644 drivers/soc/tegra/flowctrl.c
 create mode 100644 include/soc/tegra/flowctrl.h

diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index fffad2426ee4..3b33f0bb78ae 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -2,7 +2,6 @@ asflags-y				+= -march=armv7-a
 
 obj-y                                   += io.o
 obj-y                                   += irq.o
-obj-y					+= flowctrl.o
 obj-y					+= pm.o
 obj-y					+= reset.o
 obj-y					+= reset-handler.o
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index afcee04f2616..76e4c83cd5c8 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -26,12 +26,13 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 
+#include <soc/tegra/flowctrl.h>
+
 #include <asm/cpuidle.h>
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 
 #include "cpuidle.h"
-#include "flowctrl.h"
 #include "iomap.h"
 #include "irq.h"
 #include "pm.h"
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
deleted file mode 100644
index 07c688de248e..000000000000
--- a/arch/arm/mach-tegra/flowctrl.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * arch/arm/mach-tegra/flowctrl.c
- *
- * functions and macros to control the flowcontroller
- *
- * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/cpumask.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-
-#include <soc/tegra/fuse.h>
-
-#include "flowctrl.h"
-
-static u8 flowctrl_offset_halt_cpu[] = {
-	FLOW_CTRL_HALT_CPU0_EVENTS,
-	FLOW_CTRL_HALT_CPU1_EVENTS,
-	FLOW_CTRL_HALT_CPU1_EVENTS + 8,
-	FLOW_CTRL_HALT_CPU1_EVENTS + 16,
-};
-
-static u8 flowctrl_offset_cpu_csr[] = {
-	FLOW_CTRL_CPU0_CSR,
-	FLOW_CTRL_CPU1_CSR,
-	FLOW_CTRL_CPU1_CSR + 8,
-	FLOW_CTRL_CPU1_CSR + 16,
-};
-
-static void __iomem *tegra_flowctrl_base;
-
-static void flowctrl_update(u8 offset, u32 value)
-{
-	if (WARN_ONCE(!tegra_flowctrl_base,
-		      "Tegra flowctrl not initialised!\n"))
-		return;
-
-	writel(value, tegra_flowctrl_base + offset);
-
-	/* ensure the update has reached the flow controller */
-	wmb();
-	readl_relaxed(tegra_flowctrl_base + offset);
-}
-
-u32 flowctrl_read_cpu_csr(unsigned int cpuid)
-{
-	u8 offset = flowctrl_offset_cpu_csr[cpuid];
-
-	if (WARN_ONCE(!tegra_flowctrl_base,
-		      "Tegra flowctrl not initialised!\n"))
-		return 0;
-
-	return readl(tegra_flowctrl_base + offset);
-}
-
-void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value)
-{
-	return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value);
-}
-
-void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value)
-{
-	return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value);
-}
-
-void flowctrl_cpu_suspend_enter(unsigned int cpuid)
-{
-	unsigned int reg;
-	int i;
-
-	reg = flowctrl_read_cpu_csr(cpuid);
-	switch (tegra_get_chip_id()) {
-	case TEGRA20:
-		/* clear wfe bitmap */
-		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
-		/* clear wfi bitmap */
-		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
-		/* pwr gating on wfe */
-		reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
-		break;
-	case TEGRA30:
-	case TEGRA114:
-	case TEGRA124:
-		/* clear wfe bitmap */
-		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
-		/* clear wfi bitmap */
-		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
-		/* pwr gating on wfi */
-		reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
-		break;
-	}
-	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr flag */
-	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event flag */
-	reg |= FLOW_CTRL_CSR_ENABLE;			/* pwr gating */
-	flowctrl_write_cpu_csr(cpuid, reg);
-
-	for (i = 0; i < num_possible_cpus(); i++) {
-		if (i == cpuid)
-			continue;
-		reg = flowctrl_read_cpu_csr(i);
-		reg |= FLOW_CTRL_CSR_EVENT_FLAG;
-		reg |= FLOW_CTRL_CSR_INTR_FLAG;
-		flowctrl_write_cpu_csr(i, reg);
-	}
-}
-
-void flowctrl_cpu_suspend_exit(unsigned int cpuid)
-{
-	unsigned int reg;
-
-	/* Disable powergating via flow controller for CPU0 */
-	reg = flowctrl_read_cpu_csr(cpuid);
-	switch (tegra_get_chip_id()) {
-	case TEGRA20:
-		/* clear wfe bitmap */
-		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
-		/* clear wfi bitmap */
-		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
-		break;
-	case TEGRA30:
-	case TEGRA114:
-	case TEGRA124:
-		/* clear wfe bitmap */
-		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
-		/* clear wfi bitmap */
-		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
-		break;
-	}
-	reg &= ~FLOW_CTRL_CSR_ENABLE;			/* clear enable */
-	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr */
-	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event */
-	flowctrl_write_cpu_csr(cpuid, reg);
-}
-
-static const struct of_device_id matches[] __initconst = {
-	{ .compatible = "nvidia,tegra124-flowctrl" },
-	{ .compatible = "nvidia,tegra114-flowctrl" },
-	{ .compatible = "nvidia,tegra30-flowctrl" },
-	{ .compatible = "nvidia,tegra20-flowctrl" },
-	{ }
-};
-
-void __init tegra_flowctrl_init(void)
-{
-	/* hardcoded fallback if device tree node is missing */
-	unsigned long base = 0x60007000;
-	unsigned long size = SZ_4K;
-	struct device_node *np;
-
-	np = of_find_matching_node(NULL, matches);
-	if (np) {
-		struct resource res;
-
-		if (of_address_to_resource(np, 0, &res) == 0) {
-			size = resource_size(&res);
-			base = res.start;
-		}
-
-		of_node_put(np);
-	}
-
-	tegra_flowctrl_base = ioremap_nocache(base, size);
-}
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
deleted file mode 100644
index 73a9c5016c1a..000000000000
--- a/arch/arm/mach-tegra/flowctrl.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * arch/arm/mach-tegra/flowctrl.h
- *
- * functions and macros to control the flowcontroller
- *
- * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __MACH_TEGRA_FLOWCTRL_H
-#define __MACH_TEGRA_FLOWCTRL_H
-
-#define FLOW_CTRL_HALT_CPU0_EVENTS	0x0
-#define FLOW_CTRL_WAITEVENT		(2 << 29)
-#define FLOW_CTRL_WAIT_FOR_INTERRUPT	(4 << 29)
-#define FLOW_CTRL_JTAG_RESUME		(1 << 28)
-#define FLOW_CTRL_SCLK_RESUME		(1 << 27)
-#define FLOW_CTRL_HALT_CPU_IRQ		(1 << 10)
-#define	FLOW_CTRL_HALT_CPU_FIQ		(1 << 8)
-#define FLOW_CTRL_HALT_LIC_IRQ		(1 << 11)
-#define FLOW_CTRL_HALT_LIC_FIQ		(1 << 10)
-#define FLOW_CTRL_HALT_GIC_IRQ		(1 << 9)
-#define FLOW_CTRL_HALT_GIC_FIQ		(1 << 8)
-#define FLOW_CTRL_CPU0_CSR		0x8
-#define	FLOW_CTRL_CSR_INTR_FLAG		(1 << 15)
-#define FLOW_CTRL_CSR_EVENT_FLAG	(1 << 14)
-#define FLOW_CTRL_CSR_ENABLE_EXT_CRAIL	(1 << 13)
-#define FLOW_CTRL_CSR_ENABLE_EXT_NCPU	(1 << 12)
-#define FLOW_CTRL_CSR_ENABLE_EXT_MASK ( \
-		FLOW_CTRL_CSR_ENABLE_EXT_NCPU | \
-		FLOW_CTRL_CSR_ENABLE_EXT_CRAIL)
-#define FLOW_CTRL_CSR_ENABLE		(1 << 0)
-#define FLOW_CTRL_HALT_CPU1_EVENTS	0x14
-#define FLOW_CTRL_CPU1_CSR		0x18
-
-#define TEGRA20_FLOW_CTRL_CSR_WFE_CPU0		(1 << 4)
-#define TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP	(3 << 4)
-#define TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP	0
-
-#define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0		(1 << 8)
-#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP	(0xF << 4)
-#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP	(0xF << 8)
-
-#ifndef __ASSEMBLY__
-u32 flowctrl_read_cpu_csr(unsigned int cpuid);
-void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value);
-void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value);
-
-void flowctrl_cpu_suspend_enter(unsigned int cpuid);
-void flowctrl_cpu_suspend_exit(unsigned int cpuid);
-
-void tegra_flowctrl_init(void);
-#endif
-
-#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 75620ae73913..b5a2afe99101 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -21,6 +21,7 @@
 #include <linux/jiffies.h>
 #include <linux/smp.h>
 
+#include <soc/tegra/flowctrl.h>
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
 
@@ -30,7 +31,6 @@
 #include <asm/smp_scu.h>
 
 #include "common.h"
-#include "flowctrl.h"
 #include "iomap.h"
 #include "reset.h"
 
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index b0f48a3946fa..1ad5719779b0 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -27,6 +27,7 @@
 #include <linux/spinlock.h>
 #include <linux/suspend.h>
 
+#include <soc/tegra/flowctrl.h>
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/pm.h>
 #include <soc/tegra/pmc.h>
@@ -38,7 +39,6 @@
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
 
-#include "flowctrl.h"
 #include "iomap.h"
 #include "pm.h"
 #include "reset.h"
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index e3070fdab80b..805f306fa6f7 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -17,12 +17,12 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 
+#include <soc/tegra/flowctrl.h>
 #include <soc/tegra/fuse.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 
-#include "flowctrl.h"
 #include "iomap.h"
 #include "reset.h"
 #include "sleep.h"
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index f5d19667484e..5c8e638ee51a 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -20,6 +20,8 @@
 
 #include <linux/linkage.h>
 
+#include <soc/tegra/flowctrl.h>
+
 #include <asm/assembler.h>
 #include <asm/proc-fns.h>
 #include <asm/cp15.h>
@@ -27,7 +29,6 @@
 
 #include "irammap.h"
 #include "sleep.h"
-#include "flowctrl.h"
 
 #define EMC_CFG				0xc
 #define EMC_ADR_CFG			0x10
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index 16e5ff03383c..dd4a67dabd91 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -16,13 +16,13 @@
 
 #include <linux/linkage.h>
 
+#include <soc/tegra/flowctrl.h>
 #include <soc/tegra/fuse.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/assembler.h>
 #include <asm/cache.h>
 
-#include "flowctrl.h"
 #include "irammap.h"
 #include "sleep.h"
 
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index e01cbca196b5..649e9e8c7bcc 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -48,7 +48,6 @@
 #include "board.h"
 #include "common.h"
 #include "cpuidle.h"
-#include "flowctrl.h"
 #include "iomap.h"
 #include "irq.h"
 #include "pm.h"
@@ -75,7 +74,6 @@ static void __init tegra_init_early(void)
 {
 	of_register_trusted_foundations();
 	tegra_cpu_reset_handler_init();
-	tegra_flowctrl_init();
 }
 
 static void __init tegra_dt_init_irq(void)
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 208d6edb3fdb..c7e8ddfb574e 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -12,6 +12,7 @@ config ARCH_TEGRA_2x_SOC
 	select PINCTRL_TEGRA20
 	select PL310_ERRATA_727915 if CACHE_L2X0
 	select PL310_ERRATA_769419 if CACHE_L2X0
+	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select TEGRA_TIMER
 	help
@@ -24,6 +25,7 @@ config ARCH_TEGRA_3x_SOC
 	select ARM_ERRATA_764369 if SMP
 	select PINCTRL_TEGRA30
 	select PL310_ERRATA_769419 if CACHE_L2X0
+	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select TEGRA_TIMER
 	help
@@ -35,6 +37,7 @@ config ARCH_TEGRA_114_SOC
 	select ARM_ERRATA_798181 if SMP
 	select HAVE_ARM_ARCH_TIMER
 	select PINCTRL_TEGRA114
+	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select TEGRA_TIMER
 	help
@@ -45,6 +48,7 @@ config ARCH_TEGRA_124_SOC
 	bool "Enable support for Tegra124 family"
 	select HAVE_ARM_ARCH_TIMER
 	select PINCTRL_TEGRA124
+	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select TEGRA_TIMER
 	help
@@ -101,6 +105,9 @@ config ARCH_TEGRA_186_SOC
 endif
 endif
 
+config SOC_TEGRA_FLOWCTRL
+	bool
+
 config SOC_TEGRA_PMC
 	bool
 
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
index b4425e4319ff..4f81dd55e5d1 100644
--- a/drivers/soc/tegra/Makefile
+++ b/drivers/soc/tegra/Makefile
@@ -1,5 +1,6 @@
 obj-y += fuse/
 
 obj-y += common.o
+obj-$(CONFIG_SOC_TEGRA_FLOWCTRL) += flowctrl.o
 obj-$(CONFIG_SOC_TEGRA_PMC) += pmc.o
 obj-$(CONFIG_SOC_TEGRA_PMC_TEGRA186) += pmc-tegra186.o
diff --git a/drivers/soc/tegra/flowctrl.c b/drivers/soc/tegra/flowctrl.c
new file mode 100644
index 000000000000..3a5a1cb9ae90
--- /dev/null
+++ b/drivers/soc/tegra/flowctrl.c
@@ -0,0 +1,187 @@
+/*
+ * drivers/soc/tegra/flowctrl.c
+ *
+ * Functions and macros to control the flowcontroller
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <soc/tegra/common.h>
+#include <soc/tegra/flowctrl.h>
+#include <soc/tegra/fuse.h>
+
+static u8 flowctrl_offset_halt_cpu[] = {
+	FLOW_CTRL_HALT_CPU0_EVENTS,
+	FLOW_CTRL_HALT_CPU1_EVENTS,
+	FLOW_CTRL_HALT_CPU1_EVENTS + 8,
+	FLOW_CTRL_HALT_CPU1_EVENTS + 16,
+};
+
+static u8 flowctrl_offset_cpu_csr[] = {
+	FLOW_CTRL_CPU0_CSR,
+	FLOW_CTRL_CPU1_CSR,
+	FLOW_CTRL_CPU1_CSR + 8,
+	FLOW_CTRL_CPU1_CSR + 16,
+};
+
+static void __iomem *tegra_flowctrl_base;
+
+static void flowctrl_update(u8 offset, u32 value)
+{
+	if (WARN_ONCE(!tegra_flowctrl_base,
+		      "Tegra flowctrl not initialised!\n"))
+		return;
+
+	writel(value, tegra_flowctrl_base + offset);
+
+	/* ensure the update has reached the flow controller */
+	wmb();
+	readl_relaxed(tegra_flowctrl_base + offset);
+}
+
+u32 flowctrl_read_cpu_csr(unsigned int cpuid)
+{
+	u8 offset = flowctrl_offset_cpu_csr[cpuid];
+
+	if (WARN_ONCE(!tegra_flowctrl_base,
+		      "Tegra flowctrl not initialised!\n"))
+		return 0;
+
+	return readl(tegra_flowctrl_base + offset);
+}
+
+void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value)
+{
+	return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value);
+}
+
+void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value)
+{
+	return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value);
+}
+
+void flowctrl_cpu_suspend_enter(unsigned int cpuid)
+{
+	unsigned int reg;
+	int i;
+
+	reg = flowctrl_read_cpu_csr(cpuid);
+	switch (tegra_get_chip_id()) {
+	case TEGRA20:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
+		/* pwr gating on wfe */
+		reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
+		break;
+	case TEGRA30:
+	case TEGRA114:
+	case TEGRA124:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
+		/* pwr gating on wfi */
+		reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
+		break;
+	}
+	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr flag */
+	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event flag */
+	reg |= FLOW_CTRL_CSR_ENABLE;			/* pwr gating */
+	flowctrl_write_cpu_csr(cpuid, reg);
+
+	for (i = 0; i < num_possible_cpus(); i++) {
+		if (i == cpuid)
+			continue;
+		reg = flowctrl_read_cpu_csr(i);
+		reg |= FLOW_CTRL_CSR_EVENT_FLAG;
+		reg |= FLOW_CTRL_CSR_INTR_FLAG;
+		flowctrl_write_cpu_csr(i, reg);
+	}
+}
+
+void flowctrl_cpu_suspend_exit(unsigned int cpuid)
+{
+	unsigned int reg;
+
+	/* Disable powergating via flow controller for CPU0 */
+	reg = flowctrl_read_cpu_csr(cpuid);
+	switch (tegra_get_chip_id()) {
+	case TEGRA20:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
+		break;
+	case TEGRA30:
+	case TEGRA114:
+	case TEGRA124:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
+		break;
+	}
+	reg &= ~FLOW_CTRL_CSR_ENABLE;			/* clear enable */
+	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr */
+	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event */
+	flowctrl_write_cpu_csr(cpuid, reg);
+}
+
+static const struct of_device_id matches[] __initconst = {
+	{ .compatible = "nvidia,tegra124-flowctrl" },
+	{ .compatible = "nvidia,tegra114-flowctrl" },
+	{ .compatible = "nvidia,tegra30-flowctrl" },
+	{ .compatible = "nvidia,tegra20-flowctrl" },
+	{ }
+};
+
+static int __init tegra_flowctrl_init(void)
+{
+	/* hardcoded fallback if device tree node is missing */
+	unsigned long base = 0x60007000;
+	unsigned long size = SZ_4K;
+	struct device_node *np;
+
+	if (!soc_is_tegra())
+		return 0;
+
+	np = of_find_matching_node(NULL, matches);
+	if (np) {
+		struct resource res;
+
+		if (of_address_to_resource(np, 0, &res) == 0) {
+			size = resource_size(&res);
+			base = res.start;
+		}
+
+		of_node_put(np);
+	}
+
+	tegra_flowctrl_base = ioremap_nocache(base, size);
+	if (!tegra_flowctrl_base)
+		return -ENXIO;
+
+	return 0;
+}
+early_initcall(tegra_flowctrl_init);
diff --git a/include/soc/tegra/flowctrl.h b/include/soc/tegra/flowctrl.h
new file mode 100644
index 000000000000..8f86aea4024b
--- /dev/null
+++ b/include/soc/tegra/flowctrl.h
@@ -0,0 +1,82 @@
+/*
+ * Functions and macros to control the flowcontroller
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SOC_TEGRA_FLOWCTRL_H__
+#define __SOC_TEGRA_FLOWCTRL_H__
+
+#define FLOW_CTRL_HALT_CPU0_EVENTS	0x0
+#define FLOW_CTRL_WAITEVENT		(2 << 29)
+#define FLOW_CTRL_WAIT_FOR_INTERRUPT	(4 << 29)
+#define FLOW_CTRL_JTAG_RESUME		(1 << 28)
+#define FLOW_CTRL_SCLK_RESUME		(1 << 27)
+#define FLOW_CTRL_HALT_CPU_IRQ		(1 << 10)
+#define	FLOW_CTRL_HALT_CPU_FIQ		(1 << 8)
+#define FLOW_CTRL_HALT_LIC_IRQ		(1 << 11)
+#define FLOW_CTRL_HALT_LIC_FIQ		(1 << 10)
+#define FLOW_CTRL_HALT_GIC_IRQ		(1 << 9)
+#define FLOW_CTRL_HALT_GIC_FIQ		(1 << 8)
+#define FLOW_CTRL_CPU0_CSR		0x8
+#define	FLOW_CTRL_CSR_INTR_FLAG		(1 << 15)
+#define FLOW_CTRL_CSR_EVENT_FLAG	(1 << 14)
+#define FLOW_CTRL_CSR_ENABLE_EXT_CRAIL	(1 << 13)
+#define FLOW_CTRL_CSR_ENABLE_EXT_NCPU	(1 << 12)
+#define FLOW_CTRL_CSR_ENABLE_EXT_MASK ( \
+		FLOW_CTRL_CSR_ENABLE_EXT_NCPU | \
+		FLOW_CTRL_CSR_ENABLE_EXT_CRAIL)
+#define FLOW_CTRL_CSR_ENABLE		(1 << 0)
+#define FLOW_CTRL_HALT_CPU1_EVENTS	0x14
+#define FLOW_CTRL_CPU1_CSR		0x18
+
+#define TEGRA20_FLOW_CTRL_CSR_WFE_CPU0		(1 << 4)
+#define TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP	(3 << 4)
+#define TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP	0
+
+#define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0		(1 << 8)
+#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP	(0xF << 4)
+#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP	(0xF << 8)
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_SOC_TEGRA_FLOWCTRL
+u32 flowctrl_read_cpu_csr(unsigned int cpuid);
+void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value);
+void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value);
+
+void flowctrl_cpu_suspend_enter(unsigned int cpuid);
+void flowctrl_cpu_suspend_exit(unsigned int cpuid);
+#else
+static inline u32 flowctrl_read_cpu_csr(unsigned int cpuid)
+{
+	return 0;
+}
+
+static inline void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value)
+{
+}
+
+static inline void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value) {}
+
+static inline void flowctrl_cpu_suspend_enter(unsigned int cpuid)
+{
+}
+
+static inline void flowctrl_cpu_suspend_exit(unsigned int cpuid)
+{
+}
+#endif /* CONFIG_SOC_TEGRA_FLOWCTRL */
+#endif /* __ASSEMBLY */
+#endif /* __SOC_TEGRA_FLOWCTRL_H__ */
-- 
2.7.4

^ permalink raw reply related

* [PATCH V3 3/6] soc/tegra: flowctrl: Add basic platform driver
From: Jon Hunter @ 2017-03-28 12:42 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Mark Rutland, Russell King, Stephen Warren,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jon Hunter
In-Reply-To: <1490704978-22906-1-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Add a simple platform driver for the flowctrl module so that it gets
registered as a proper device.

Signed-off-by: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/soc/tegra/flowctrl.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/tegra/flowctrl.c b/drivers/soc/tegra/flowctrl.c
index 3a5a1cb9ae90..25eddfc8475d 100644
--- a/drivers/soc/tegra/flowctrl.c
+++ b/drivers/soc/tegra/flowctrl.c
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 
 #include <soc/tegra/common.h>
 #include <soc/tegra/flowctrl.h>
@@ -47,7 +48,7 @@ static void __iomem *tegra_flowctrl_base;
 
 static void flowctrl_update(u8 offset, u32 value)
 {
-	if (WARN_ONCE(!tegra_flowctrl_base,
+	if (WARN_ONCE(IS_ERR_OR_NULL(tegra_flowctrl_base),
 		      "Tegra flowctrl not initialised!\n"))
 		return;
 
@@ -62,7 +63,7 @@ u32 flowctrl_read_cpu_csr(unsigned int cpuid)
 {
 	u8 offset = flowctrl_offset_cpu_csr[cpuid];
 
-	if (WARN_ONCE(!tegra_flowctrl_base,
+	if (WARN_ONCE(IS_ERR_OR_NULL(tegra_flowctrl_base),
 		      "Tegra flowctrl not initialised!\n"))
 		return 0;
 
@@ -148,7 +149,22 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
 	flowctrl_write_cpu_csr(cpuid, reg);
 }
 
-static const struct of_device_id matches[] __initconst = {
+static int tegra_flowctrl_probe(struct platform_device *pdev)
+{
+	void __iomem *base = tegra_flowctrl_base;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tegra_flowctrl_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tegra_flowctrl_base))
+		return PTR_ERR(base);
+
+	iounmap(base);
+
+	return 0;
+}
+
+static const struct of_device_id tegra_flowctrl_match[] = {
 	{ .compatible = "nvidia,tegra124-flowctrl" },
 	{ .compatible = "nvidia,tegra114-flowctrl" },
 	{ .compatible = "nvidia,tegra30-flowctrl" },
@@ -156,6 +172,16 @@ static const struct of_device_id matches[] __initconst = {
 	{ }
 };
 
+static struct platform_driver tegra_flowctrl_driver = {
+	.driver = {
+		.name = "tegra-flowctrl",
+		.suppress_bind_attrs = true,
+		.of_match_table = tegra_flowctrl_match,
+	},
+	.probe = tegra_flowctrl_probe,
+};
+builtin_platform_driver(tegra_flowctrl_driver);
+
 static int __init tegra_flowctrl_init(void)
 {
 	/* hardcoded fallback if device tree node is missing */
@@ -166,7 +192,7 @@ static int __init tegra_flowctrl_init(void)
 	if (!soc_is_tegra())
 		return 0;
 
-	np = of_find_matching_node(NULL, matches);
+	np = of_find_matching_node(NULL, tegra_flowctrl_match);
 	if (np) {
 		struct resource res;
 
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH V3 4/6] dt-bindings: tegra: Update compatible strings for Tegra flowctrl
From: Jon Hunter @ 2017-03-28 12:42 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mark Rutland, devicetree, Stephen Warren, Russell King,
	Jon Hunter, Rob Herring, linux-tegra, linux-arm-kernel
In-Reply-To: <1490704978-22906-1-git-send-email-jonathanh@nvidia.com>

Update the compatible strings for Tegra Flow Control driver to match
the device-tree source files for Tegra.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 .../devicetree/bindings/arm/tegra/nvidia,tegra20-flowctrl.txt     | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-flowctrl.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-flowctrl.txt
index ccf0adddc820..a855c1bffc0f 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-flowctrl.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-flowctrl.txt
@@ -1,7 +1,13 @@
 NVIDIA Tegra Flow Controller
 
 Required properties:
-- compatible: Should be "nvidia,tegra<chip>-flowctrl"
+- compatible: Should contain one of the following:
+  - "nvidia,tegra20-flowctrl": for Tegra20
+  - "nvidia,tegra30-flowctrl": for Tegra30
+  - "nvidia,tegra114-flowctrl": for Tegra114
+  - "nvidia,tegra124-flowctrl": for Tegra124
+  - "nvidia,tegra132-flowctrl", "nvidia,tegra124-flowctrl": for Tegra132
+  - "nvidia,tegra210-flowctrl": for Tegra210
 - reg: Should contain one register range (address and length)
 
 Example:
-- 
2.7.4

^ permalink raw reply related

* [PATCH V3 5/6] arm64: tegra: Update the Tegra132 flowctrl compatible string
From: Jon Hunter @ 2017-03-28 12:42 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mark Rutland, devicetree, Stephen Warren, Russell King,
	Jon Hunter, Rob Herring, linux-tegra, linux-arm-kernel
In-Reply-To: <1490704978-22906-1-git-send-email-jonathanh@nvidia.com>

Update the Tegra132 flowctrl compatible string to include
"nvidia,tegra132-flowctrl" so it is aligned with the flowctrl binding
documentation.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra132.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
index 3f3a46a4bd01..2b17936ac5be 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -224,7 +224,7 @@
 	};
 
 	flow-controller@60007000 {
-		compatible = "nvidia,tegra124-flowctrl";
+		compatible = "nvidia,tegra132-flowctrl", "nvidia,tegra124-flowctrl";
 		reg = <0x0 0x60007000 0x0 0x1000>;
 	};
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH V3 6/6] soc/tegra: Add initial flowctrl support for Tegra132/210
From: Jon Hunter @ 2017-03-28 12:42 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mark Rutland, devicetree, Stephen Warren, Russell King,
	Jon Hunter, Rob Herring, linux-tegra, linux-arm-kernel
In-Reply-To: <1490704978-22906-1-git-send-email-jonathanh@nvidia.com>

Tegra132 and Tegra210 support the flowctrl module and so add initial
support for these devices.

Please note that Tegra186 does not support the flowctrl module, so
update the initialisation function such that we do not fall back and
attempt to map the 'hardcoded' address range for Tegra186. Furthermore
64-bit Tegra devices have always had the flowctrl node defined in their
device-tree and so only use the 'hardcoded' addresses for 32-bit Tegra
devices.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/Kconfig    |  2 ++
 drivers/soc/tegra/flowctrl.c | 31 +++++++++++++++++++++----------
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index c7e8ddfb574e..dcf088db40b6 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -63,6 +63,7 @@ if ARM64
 config ARCH_TEGRA_132_SOC
 	bool "NVIDIA Tegra132 SoC"
 	select PINCTRL_TEGRA124
+	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	help
 	  Enable support for NVIDIA Tegra132 SoC, based on the Denver
@@ -73,6 +74,7 @@ config ARCH_TEGRA_132_SOC
 config ARCH_TEGRA_210_SOC
 	bool "NVIDIA Tegra210 SoC"
 	select PINCTRL_TEGRA210
+	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	help
 	  Enable support for the NVIDIA Tegra210 SoC. Also known as Tegra X1,
diff --git a/drivers/soc/tegra/flowctrl.c b/drivers/soc/tegra/flowctrl.c
index 25eddfc8475d..0e345c05fc65 100644
--- a/drivers/soc/tegra/flowctrl.c
+++ b/drivers/soc/tegra/flowctrl.c
@@ -165,6 +165,7 @@ static int tegra_flowctrl_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id tegra_flowctrl_match[] = {
+	{ .compatible = "nvidia,tegra210-flowctrl" },
 	{ .compatible = "nvidia,tegra124-flowctrl" },
 	{ .compatible = "nvidia,tegra114-flowctrl" },
 	{ .compatible = "nvidia,tegra30-flowctrl" },
@@ -184,9 +185,7 @@ builtin_platform_driver(tegra_flowctrl_driver);
 
 static int __init tegra_flowctrl_init(void)
 {
-	/* hardcoded fallback if device tree node is missing */
-	unsigned long base = 0x60007000;
-	unsigned long size = SZ_4K;
+	struct resource res;
 	struct device_node *np;
 
 	if (!soc_is_tegra())
@@ -194,17 +193,29 @@ static int __init tegra_flowctrl_init(void)
 
 	np = of_find_matching_node(NULL, tegra_flowctrl_match);
 	if (np) {
-		struct resource res;
-
-		if (of_address_to_resource(np, 0, &res) == 0) {
-			size = resource_size(&res);
-			base = res.start;
+		if (of_address_to_resource(np, 0, &res) < 0) {
+			pr_err("failed to get flowctrl register\n");
+			return -ENXIO;
 		}
-
 		of_node_put(np);
+	} else if (IS_ENABLED(CONFIG_ARM)) {
+		/*
+		 * Hardcoded fallback for 32-bit Tegra
+		 * devices if device tree node is missing.
+		 */
+		res.start = 0x60007000;
+		res.end = 0x60007fff;
+		res.flags = IORESOURCE_MEM;
+	} else {
+		/*
+		 * At this point we're running on a Tegra,
+		 * that doesn't support the flow controller
+		 * (eg. Tegra186), so just return.
+		 */
+		return 0;
 	}
 
-	tegra_flowctrl_base = ioremap_nocache(base, size);
+	tegra_flowctrl_base = ioremap_nocache(res.start, resource_size(&res));
 	if (!tegra_flowctrl_base)
 		return -ENXIO;
 
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH v2 2/3] device property: Fix reading pset strings using array access functions
From: Mika Westerberg @ 2017-03-28 12:48 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-acpi, devicetree, rafael, sudeep.holla, lorenzo.pieralisi,
	mark.rutland, broonie, robh, ahs3
In-Reply-To: <1490703739-28270-3-git-send-email-sakari.ailus@linux.intel.com>

On Tue, Mar 28, 2017 at 03:22:18PM +0300, Sakari Ailus wrote:
> The length field value of non-array string properties is the length of the
> string itself. Non-array string properties thus require specific handling.
> Fix this.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>

^ permalink raw reply

* Re: [PATCH v2 3/3] device property: fwnode_property_read_string_array() returns nr of strings
From: Mika Westerberg @ 2017-03-28 12:52 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, rafael-DgEjT+Ai2ygdnm+yROfE0A,
	sudeep.holla-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	robh-DgEjT+Ai2ygdnm+yROfE0A, ahs3-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <1490703739-28270-4-git-send-email-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

On Tue, Mar 28, 2017 at 03:22:19PM +0300, Sakari Ailus wrote:
> -		ret = acpi_copy_property_array_string(items, (char **)val, nval);
> +		ret = acpi_copy_property_array_string(
> +			items, (char **)val,
> +			min_t(u32, nval, obj->package.count));

I think this looks better if written like:

		ret = acpi_copy_property_array_string(items, (char **)val,
					min_t(u32, nval, obj->package.count));

Regardless of that,

Reviewed-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 5/7] pinctrl: aramda-37xx: Add irqchip support
From: Linus Walleij @ 2017-03-28 13:04 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: linux-gpio@vger.kernel.org, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Thomas Petazzoni,
	linux-arm-kernel@lists.infradead.org, Rob Herring,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	Nadav Haklai, Victor Gu, Marcin Wojtas, Wilson Ding, Hua Jing,
	Neta Zur Hershkovits
In-Reply-To: <87vaqtadry.fsf@free-electrons.com>

On Tue, Mar 28, 2017 at 12:36 PM, Gregory CLEMENT
<gregory.clement@free-electrons.com> wrote:
>  On lun., mars 27 2017, Linus Walleij <linus.walleij@linaro.org> wrote:

>>> +                       u32 virq = irq_linear_revmap(d, hwirq +
>>> +                                                    i * GPIO_PER_REG);
>>
>> Use irq_find_mapping() instead please.
>
> As we are in the interrupt handler I chose to use this function because
> according to its documentation: "This is a fast path alternative to
> irq_find_mapping() that can be called directly by irq controller code to
> save a handful of instructions".
>
> The only restriction is "It is always safe to call, but won't find irqs
> mapped using the radix tree.". So I think that for this driver it is
> okay.

So you are relying on the core code in gpiolib to select a linear
map. That is implicit semantics, and either all drivers using
GPIOLIB_IRQCHIP should be changed to irq_linear_revmap()
or all stay with irq_find_mapping().

In this case, I doubt it that you are actually so timing critical that
it matters. Please use irq_find_mapping().

>>> +       nr_irq_parent = of_irq_count(np);
>>> +       spin_lock_init(&info->irq_lock);
>>> +
>>> +       if (!nr_irq_parent) {
>>> +               dev_err(&pdev->dev, "Invalid or no IRQ\n");
>>> +               return 0;
>>> +       }
>>
>> What if it is > 1? That doesn't seem to work but will pass this
>> check silently.
>
> If we have nr_irq_parent > 1, it will work and it is actually expected.

Ah, I get it. Nice.

>>> +       ret = gpiochip_irqchip_add(gc, irqchip, 0,
>>> +                                  handle_level_irq, IRQ_TYPE_NONE);
>>
>> If you also set up the handler in .set_type() you can assign
>> handle_bad_irq() here and let .set_type set the right handler
>> as e.g. drivers/gpio/gpio-pl061.c.
>
> Well the hardware can only manage the edge trigger, so there is no
> benefit to modify it each time we want to change the kind of edge we
> want (raising or falling). But your comment make me realized that I used
> the wrong one, I will move to handle_edge_irq in the v4.

Ooops, yeah handle_edge_irq() is what calls the ACK callback.

>>> +       for (i = 0; i < nrirqs; i++) {
>>> +               struct irq_data *d = irq_get_irq_data(gc->irq_base + i);
>>> +
>>> +               d->mask = 1 << (i % GPIO_PER_REG);
>>> +       }
>>
>> What is this? It looks like a big hack. At least put in a fat
>> comment about what is going on and why.
>
> I can reuse a part of the commit log here: "The only unusual "feature"
> is that many interrupts are connected to the parent interrupt
> controller. But we do not take advantage of this and use the chained irq
> with all of them."

What you're doing is mocking around with core irqchip semantics.
Is ->mask really supposed to be played around with from the outsid
like this?

Anyways: BIT(i % GPIO_PER_REG) is nicer.

>>> +       for (i = 0; i < nr_irq_parent; i++) {
>>> +               int irq = irq_of_parse_and_map(np, i);
>>
>> I think gpiochip_irqchip_add() will do this for you already,
>> as it calls irq_create_mapping() for all offsets which will call
>> irq_of_parse_and_map() am I right?
>
> After reading the code, it doesn't seem it is the case. At least there
> is no irq_of_parse_and_map() call from gpiochip_irqchip_add(). And waht
> we need here is to associate each IRQ to the same GPIO handler.
>
> I can still try without this line to confirm it.

It has irq_create_mapping(gpiochip->irqdomain, offset); that get
called for every IRQ, and that will eventually call irq_of_parse_and_map()
if the IRQs are defined in the device tree. (IIRC)

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v2 3/3] device property: fwnode_property_read_string_array() returns nr of strings
From: Sakari Ailus @ 2017-03-28 13:07 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Sakari Ailus, linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, rafael-DgEjT+Ai2ygdnm+yROfE0A,
	sudeep.holla-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	robh-DgEjT+Ai2ygdnm+yROfE0A, ahs3-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <20170328125231.GP2957-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>

Hi Mika,

Thank you for the review!

On Tue, Mar 28, 2017 at 03:52:31PM +0300, Mika Westerberg wrote:
> On Tue, Mar 28, 2017 at 03:22:19PM +0300, Sakari Ailus wrote:
> > -		ret = acpi_copy_property_array_string(items, (char **)val, nval);
> > +		ret = acpi_copy_property_array_string(
> > +			items, (char **)val,
> > +			min_t(u32, nval, obj->package.count));
> 
> I think this looks better if written like:
> 
> 		ret = acpi_copy_property_array_string(items, (char **)val,
> 					min_t(u32, nval, obj->package.count));

I prefer the former although I have no strong opinion either way. Using an
indentation that is automatically intended by a text editor is also an
advantage.

I can change it if you insist. :-)

> 
> Regardless of that,
> 
> Reviewed-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Thanks!

-- 
Regards,

Sakari Ailus
e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org	XMPP: sailus-PCDdDYkjdNMDXYZnReoRVg@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2] ARM: dts: am335x-baltos: add LED support
From: yegorslists-gM/Ye1E23mwN+BqQ9rBEUg @ 2017-03-28 13:09 UTC (permalink / raw)
  To: linux-omap-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Yegor Yefremov

From: Yegor Yefremov <yegorslists-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>

All three devices provide GPIO based LEDs named power,
wlan and app.

Place LEDs definition into a separate dtsi file as not all
devices including am335x-baltos.dtsi have the same LED layout.

Signed-off-by: Yegor Yefremov <yegorslists-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
---
Changes v1 -> v2:
  - move LEDs definition to a separate dtsi file (Tony Lindgren)

 arch/arm/boot/dts/am335x-baltos-ir2110.dts |  1 +
 arch/arm/boot/dts/am335x-baltos-ir3220.dts |  1 +
 arch/arm/boot/dts/am335x-baltos-ir5221.dts |  1 +
 arch/arm/boot/dts/am335x-baltos-leds.dtsi  | 50 ++++++++++++++++++++++++++++++
 4 files changed, 53 insertions(+)
 create mode 100644 arch/arm/boot/dts/am335x-baltos-leds.dtsi

diff --git a/arch/arm/boot/dts/am335x-baltos-ir2110.dts b/arch/arm/boot/dts/am335x-baltos-ir2110.dts
index 501c752..75de1e7 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir2110.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir2110.dts
@@ -14,6 +14,7 @@
 /dts-v1/;
 
 #include "am335x-baltos.dtsi"
+#include "am335x-baltos-leds.dtsi"
 
 / {
 	model = "OnRISC Baltos iR 2110";
diff --git a/arch/arm/boot/dts/am335x-baltos-ir3220.dts b/arch/arm/boot/dts/am335x-baltos-ir3220.dts
index 19f53b8..46df1b2 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir3220.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir3220.dts
@@ -14,6 +14,7 @@
 /dts-v1/;
 
 #include "am335x-baltos.dtsi"
+#include "am335x-baltos-leds.dtsi"
 
 / {
 	model = "OnRISC Baltos iR 3220";
diff --git a/arch/arm/boot/dts/am335x-baltos-ir5221.dts b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
index 2b9d7f4..5d56355 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir5221.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
@@ -14,6 +14,7 @@
 /dts-v1/;
 
 #include "am335x-baltos.dtsi"
+#include "am335x-baltos-leds.dtsi"
 
 / {
 	model = "OnRISC Baltos iR 5221";
diff --git a/arch/arm/boot/dts/am335x-baltos-leds.dtsi b/arch/arm/boot/dts/am335x-baltos-leds.dtsi
new file mode 100644
index 0000000..3ab1767
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-baltos-leds.dtsi
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * VScom OnRISC
+ * http://www.vscom.de
+ */
+
+/*#include "am33xx.dtsi"*/
+
+/ {
+	leds {
+		pinctrl-names = "default";
+		pinctrl-0 = <&user_leds>;
+
+		compatible = "gpio-leds";
+
+		power {
+			label = "onrisc:red:power";
+			linux,default-trigger = "default-on";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+		wlan {
+			label = "onrisc:blue:wlan";
+			gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+		app {
+			label = "onrisc:green:app";
+			gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+};
+
+&am33xx_pinmux {
+	user_leds: pinmux_user_leds {
+		pinctrl-single,pins = <
+			AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* mii1_col.gpio3_0 PWR LED */
+			AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* mii1_txd3.gpio0_16 WLAN LED */
+			AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* mii1_txd2.gpio0_17 APP LED */
+		>;
+	};
+};
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH 5/8] ARM64: dts: meson-gxbb: add i2s output pins
From: Linus Walleij @ 2017-03-28 13:15 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: devicetree@vger.kernel.org, Kevin Hilman,
	linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
	Carlo Caione, open list:ARM/Amlogic Meson...,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20170323165101.29262-6-jbrunet@baylibre.com>

On Thu, Mar 23, 2017 at 5:50 PM, Jerome Brunet <jbrunet@baylibre.com> wrote:

> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

For this and the other Meson DTS patches.

Please funnel these through the apropriate ARM SoC-feed tree.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH 1/2] drm/bridge: ti-tfp410: support hpd via gpio
From: Jyri Sarha @ 2017-03-28 13:32 UTC (permalink / raw)
  To: Archit Taneja, Christopher Spinrath
  Cc: Mark Rutland, devicetree@vger.kernel.org,
	Russell King - ARM Linux, DRI mailing list, robh+dt@kernel.org,
	Igor Grinberg, Sascha Hauer, Fabio Estevam, Shawn Guo,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <d6b2391f-3e4a-2761-b6a0-8997d2c78600@codeaurora.org>

On 03/27/17 08:58, Archit Taneja wrote:
> Hi,
> 
> On 03/07/2017 03:21 AM, Christopher Spinrath wrote:
>> Hi Fabio,
>>
>> On 03/06/2017 10:46 PM, Fabio Estevam wrote:
>>> Hi Christopher,
>>>
>>> On Mon, Mar 6, 2017 at 6:40 PM, 
>>> <christopher.spinrath@rwth-aachen.de> wrote:
>>>> From: Christopher Spinrath <christopher.spinrath@rwth-aachen.de>
>>>>
>>>> On some boards the hpd pin of a hdmi connector is wired up to a gpio
>>>> pin. Since in the DRM world the tfp410 driver is responsible for
>>>> handling the connector, add support for hpd gpios in this very driver.
>>>>
>>>> Signed-off-by: Christopher Spinrath
>>>> <christopher.spinrath@rwth-aachen.de>
>>>> ---
>>>>  drivers/gpu/drm/bridge/ti-tfp410.c | 72
>>>> ++++++++++++++++++++++++++++++++++++--
>>>
...
>>
> 
> The patch looks good to me.
> 
> Jyri,
> 
> Is it possible for you to verify this on Beaglebone platform?
> 

If I read my BeagleBone DVI-D Cape docs right, it does not have the HPD
pin connected. At least it does not mention any gpio that could be used
for the purpose. So I can not easily test this patch in real world
situation. For what it is worth the patch looks ok to me too.

Best regards,
Jyri

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v5 1/5] usb: dwc2: Add support for STM32F429/439/469 USB OTG HS/FS in FS mode (internal PHY)
From: Felipe Balbi @ 2017-03-28 13:36 UTC (permalink / raw)
  To: Alexandre Torgue, John Youn, Bruno Herrera, robh+dt@kernel.org,
	mark.rutland@arm.com, mcoquelin.stm32@gmail.com
  Cc: devicetree@vger.kernel.org, linux-usb@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <58187797-2c11-c75b-571c-27fe64578099@st.com>


Hi,

Alexandre Torgue <alexandre.torgue@st.com> writes:
> Hi John,
>
> On 02/01/2017 04:37 AM, John Youn wrote:
>> On 1/31/2017 5:26 PM, Bruno Herrera wrote:
>>> This patch introduces a new parameter to activate USB OTG HS/FS core
>>> embedded phy transceiver. The STM32F4x9 SoC uses the GGPIO register
>>> to enable the transceiver.
>>> Also add the dwc2_set_params function for stm32f4 otg fs.
>>>
>>> Signed-off-by: Bruno Herrera <bruherrera@gmail.com>
>>
>> Acked-by: John Youn <johnyoun@synopsys.com>
>>
> Do you plan to take those patches on your pull-request for 4.12?
> I was wondering if I take machine parts (DT) in my pull request for 4.12 
> or if I wait an official version with driver part merged.

patches already in my queue for v4.12

-- 
balbi

^ permalink raw reply

* Re: [PATCH 0/5] rtc: Reuse rtc-sh driver to support RZ/A1
From: bobethtarsi3-Re5JQEeQqe8AvxtiuMwx3w @ 2017-03-28 13:38 UTC (permalink / raw)
  To: rtc-linux
  Cc: a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	horms+renesas-/R6kz+dDXgpPR4JQBCEnsQ,
	geert-Td1EMuHUCqxL1ZNQvxDV9g, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA,
	chris.brandt-zM6kxYcvzFBBDgjK7y7TUQ
In-Reply-To: <20170316175112.27913-1-chris.brandt-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>


[-- Attachment #1.1: Type: text/plain, Size: 1072 bytes --]


>
>
> Thank you for contacting Mr PAMPHILE this gentleman who gave me a smile 
> again by offering me a loan of 32,000 Dollars and has two of my colleagues 
> who have also received loans at his level without problems instead of 
> getting you through Unwilling individuals, who take to work to defraud the 
> innocent. If you need funding; Lending money or any project to achieve this 
> man will help you achieve it and support you financially.
> Here is his mail: phamphileserge-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org
>

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #1.2: Type: text/html, Size: 1644 bytes --]

[-- Attachment #2: 113791658.jpg --]
[-- Type: image/jpeg, Size: 37896 bytes --]

^ permalink raw reply

* Re: [PATCH v5 1/5] usb: dwc2: Add support for STM32F429/439/469 USB OTG HS/FS in FS mode (internal PHY)
From: Alexandre Torgue @ 2017-03-28 13:49 UTC (permalink / raw)
  To: Felipe Balbi, John Youn, Bruno Herrera,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	mark.rutland-5wv7dgnIgG8@public.gmane.org,
	mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <8760ith6a6.fsf-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>



On 03/28/2017 03:36 PM, Felipe Balbi wrote:
>
> Hi,
>
> Alexandre Torgue <alexandre.torgue-qxv4g6HH51o@public.gmane.org> writes:
>> Hi John,
>>
>> On 02/01/2017 04:37 AM, John Youn wrote:
>>> On 1/31/2017 5:26 PM, Bruno Herrera wrote:
>>>> This patch introduces a new parameter to activate USB OTG HS/FS core
>>>> embedded phy transceiver. The STM32F4x9 SoC uses the GGPIO register
>>>> to enable the transceiver.
>>>> Also add the dwc2_set_params function for stm32f4 otg fs.
>>>>
>>>> Signed-off-by: Bruno Herrera <bruherrera-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>>
>>> Acked-by: John Youn <johnyoun-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
>>>
>> Do you plan to take those patches on your pull-request for 4.12?
>> I was wondering if I take machine parts (DT) in my pull request for 4.12
>> or if I wait an official version with driver part merged.
>
> patches already in my queue for v4.12

Thanks for info.

Regards
Alex

>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 0/4] gpio: mvebu: Add PWM fan support
From: Andrew Lunn @ 2017-03-28 13:57 UTC (permalink / raw)
  To: Ralph Sennhauser
  Cc: Mark Rutland, Alexandre Courbot, Jason Cooper, linux-pwm,
	Linus Walleij, Russell King, Rob Herring, linux-kernel,
	linux-gpio, devicetree, Thierry Reding, Gregory Clement,
	Imre Kaloz, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20170327194301.1104-1-ralph.sennhauser@gmail.com>

> Pending:
>   * npwm = 1? I vote no if that counts. ;) (suggested by Thierry Reding)
>   * Tested-by: Andrew Lunn for v1 needs renewing

Hi Ralph

I just tested this version. Fan it still keeping my Mamba board cool.

Tested-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* Re: [PATCH v6 17/39] platform: add video-multiplexer subdevice driver
From: Vladimir Zapolskiy @ 2017-03-28 14:12 UTC (permalink / raw)
  To: Steve Longerbeam, robh+dt, mark.rutland, shawnguo, kernel,
	fabio.estevam, linux, mchehab, hverkuil, nick, markus.heiser,
	p.zabel, laurent.pinchart+renesas, bparrot, geert, arnd,
	sudipm.mukherjee, minghsiu.tsai, tiffany.lin,
	jean-christophe.trotin, horms+renesas, niklas.soderlund+renesas,
	robert.jarzmik, songjun.wu, andrew-ct.chen, gregkh, shuah,
	sakari.ailus, pavel
  Cc: devel, devicetree, Steve Longerbeam, Sascha Hauer, linux-kernel,
	linux-arm-kernel, linux-media
In-Reply-To: <1490661656-10318-18-git-send-email-steve_longerbeam@mentor.com>

Hi Steve,

On 03/28/2017 03:40 AM, Steve Longerbeam wrote:
> From: Philipp Zabel <p.zabel@pengutronix.de>
> 
> This driver can handle SoC internal and external video bus multiplexers,
> controlled either by register bit fields or by a GPIO. The subdevice
> passes through frame interval and mbus configuration of the active input
> to the output side.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> 
> - fixed a cut&paste error in vidsw_remove(): v4l2_async_register_subdev()
>   should be unregister.
> 
> - added media_entity_cleanup() to vidsw_remove().
> 
> - added missing MODULE_DEVICE_TABLE().
>   Suggested-by: Javier Martinez Canillas <javier@dowhile0.org>
> 
> - there was a line left over from a previous iteration that negated
>   the new way of determining the pad count just before it which
>   has been removed (num_pads = of_get_child_count(np)).
> 
> - removed [gs]_frame_interval ops. timeperframe is not used anywhwere
>   in this subdev, and currently it has no control over frame rate.
> 
> - add link_validate to media_entity_operations.
> 
> - moved devicetree binding doc to a separate commit.
> 
> - Philipp Zabel has developed a set of patches that allow adding
>   to the subdev async notifier waiting list using a chaining method
>   from the async registered callbacks (v4l2_of_subdev_registered()
>   and the prep patches for that). For now, I've removed the use of
>   v4l2_of_subdev_registered() for the vidmux driver's registered
>   callback. This doesn't affect the functionality of this driver,
>   but allows for it to be merged now, before adding the chaining
>   support.
> 
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
> ---
>  drivers/media/platform/Kconfig             |   8 +
>  drivers/media/platform/Makefile            |   2 +
>  drivers/media/platform/video-multiplexer.c | 451 +++++++++++++++++++++++++++++
>  3 files changed, 461 insertions(+)
>  create mode 100644 drivers/media/platform/video-multiplexer.c
> 
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index ab0bb48..c9b8d9c 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -74,6 +74,14 @@ config VIDEO_M32R_AR_M64278
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called arv.
>  
> +config VIDEO_MULTIPLEXER
> +	tristate "Video Multiplexer"
> +	depends on VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER

+ depends on OF

> +	help
> +	  This driver provides support for SoC internal N:1 video bus
> +	  multiplexers controlled by register bitfields as well as external
> +	  2:1 video multiplexers controlled by a single GPIO.
> +

[snip]

> +static int vidsw_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct of_endpoint endpoint;
> +	struct device_node *ep;
> +	struct reg_field field;
> +	struct vidsw *vidsw;
> +	struct regmap *map;
> +	unsigned int num_pads;
> +	int ret;
> +
> +	vidsw = devm_kzalloc(&pdev->dev, sizeof(*vidsw), GFP_KERNEL);
> +	if (!vidsw)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, vidsw);
> +
> +	v4l2_subdev_init(&vidsw->subdev, &vidsw_subdev_ops);
> +	snprintf(vidsw->subdev.name, sizeof(vidsw->subdev.name), "%s",
> +			np->name);

.... or oops here       ^^^^^^^^^.

> +	vidsw->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	vidsw->subdev.dev = &pdev->dev;
> +
> +	/*
> +	 * The largest numbered port is the output port. It determines
> +	 * total number of pads
> +	 */
> +	num_pads = 0;
> +	for_each_endpoint_of_node(np, ep) {
> +		of_graph_parse_endpoint(ep, &endpoint);
> +		num_pads = max(num_pads, endpoint.port + 1);
> +	}
> +
> +	if (num_pads < 2) {
> +		dev_err(&pdev->dev, "Not enough ports %d\n", num_pads);
> +		return -EINVAL;
> +	}

This unveils another runtime dependency on OF.

> +
> +	ret = of_get_reg_field(np, &field);
> +	if (ret == 0) {
> +		map = syscon_node_to_regmap(np->parent);
> +		if (!map) {
> +			dev_err(&pdev->dev, "Failed to get syscon register map\n");
> +			return PTR_ERR(map);
> +		}
> +
> +		vidsw->field = devm_regmap_field_alloc(&pdev->dev, map, field);
> +		if (IS_ERR(vidsw->field)) {
> +			dev_err(&pdev->dev, "Failed to allocate regmap field\n");
> +			return PTR_ERR(vidsw->field);
> +		}
> +
> +		regmap_field_read(vidsw->field, &vidsw->active);
> +	} else {
> +		if (num_pads > 3) {
> +			dev_err(&pdev->dev, "Too many ports %d\n", num_pads);
> +			return -EINVAL;
> +		}
> +
> +		vidsw->gpio = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW);
> +		if (IS_ERR(vidsw->gpio)) {
> +			dev_warn(&pdev->dev,
> +				 "could not request control gpio: %d\n", ret);
> +			vidsw->gpio = NULL;
> +		}
> +
> +		vidsw->active = gpiod_get_value(vidsw->gpio) ? 1 : 0;

vidsw->active is always set to 0 ?

> +	}
> +
> +	vidsw->num_pads = num_pads;
> +	vidsw->pads = devm_kzalloc(&pdev->dev, sizeof(*vidsw->pads) * num_pads,
> +			GFP_KERNEL);
> +	vidsw->format_mbus = devm_kzalloc(&pdev->dev,
> +			sizeof(*vidsw->format_mbus) * num_pads, GFP_KERNEL);
> +	vidsw->endpoint = devm_kzalloc(&pdev->dev,
> +			sizeof(*vidsw->endpoint) * (num_pads - 1), GFP_KERNEL);
> +
> +	ret = vidsw_async_init(vidsw, np);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +

--
With best wishes,
Vladimir

^ permalink raw reply

* Re: [RFC PATCH 1/3] of/pci: dma-ranges to account highest possible host bridge dma_mask
From: Rob Herring @ 2017-03-28 14:13 UTC (permalink / raw)
  To: Oza Oza
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux IOMMU,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <CAMSpPPdnQdWeyTsnESRFx52gtxQLxwfPQwQgDFSN=katfW7suA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Tue, Mar 28, 2017 at 12:27 AM, Oza Oza <oza.oza-dY08KVG/lbpWk0Htik3J/w@public.gmane.org> wrote:
> On Mon, Mar 27, 2017 at 8:16 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> On Sat, Mar 25, 2017 at 12:31 AM, Oza Pawandeep <oza.oza-dY08KVG/lbpWk0Htik3J/w@public.gmane.org> wrote:
>>> it is possible that PCI device supports 64-bit DMA addressing,
>>> and thus it's driver sets device's dma_mask to DMA_BIT_MASK(64),
>>> however PCI host bridge may have limitations on the inbound
>>> transaction addressing. As an example, consider NVME SSD device
>>> connected to iproc-PCIe controller.
>>>
>>> Currently, the IOMMU DMA ops only considers PCI device dma_mask
>>> when allocating an IOVA. This is particularly problematic on
>>> ARM/ARM64 SOCs where the IOMMU (i.e. SMMU) translates IOVA to
>>> PA for in-bound transactions only after PCI Host has forwarded
>>> these transactions on SOC IO bus. This means on such ARM/ARM64
>>> SOCs the IOVA of in-bound transactions has to honor the addressing
>>> restrictions of the PCI Host.
>>>
>>> current pcie frmework and of framework integration assumes dma-ranges
>>> in a way where memory-mapped devices define their dma-ranges.
>>> dma-ranges: (child-bus-address, parent-bus-address, length).
>>>
>>> but iproc based SOCs and even Rcar based SOCs has PCI world dma-ranges.
>>> dma-ranges = <0x43000000 0x00 0x00 0x00 0x00 0x80 0x00>;
>>
>> If you implement a common function, then I expect to see other users
>> converted to use it. There's also PCI hosts in arch/powerpc that parse
>> dma-ranges.
>
> the common function should be similar to what
> of_pci_get_host_bridge_resources is doing right now.
> it parses ranges property right now.
>
> the new function would look look following.
>
> of_pci_get_dma_ranges(struct device_node *dev, struct list_head *resources)
> where resources would return the dma-ranges.
>
> but right now if you see the patch, of_dma_configure calls the new
> function, which actually returns the largest possible size.
> so this new function has to be generic in a way where other PCI hosts
> can use it. but certainly iproc(Broadcom SOC) , rcar based SOCs can
> use it for sure.
>
> although having powerpc using it;  is a separate exercise, since I do
> not have any access to other PCI hosts such as powerpc. but we can
> workout with them on thsi forum if required.

You don't need h/w. You can analyze what parts are common, write
patches to convert to common implementation, and build test. The PPC
and rcar folks can test on h/w.

Rob

^ permalink raw reply

* [PATCH v2 1/8] regulator: arizona-micsupp: Avoid potential memory leak reading init_data
From: Charles Keepax @ 2017-03-28 14:14 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, patches, lgirdwood,
	linux-kernel, robh+dt, lee.jones

The device argument passed to of_get_regulator_init_data is used to
do some devres memory allocation. Currently the driver passes the MFD
device pointer to this function, this could result in the init_data
allocation being leaked if the regulator is unbound but the MFD isn't.

Correct this issue by correctly passing the local platform device.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

New patch in the series since v1.

 drivers/regulator/arizona-micsupp.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index 22bd714..5e38861 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -199,7 +199,8 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
 	.num_consumer_supplies = 1,
 };
 
-static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
+static int arizona_micsupp_of_get_pdata(struct device *dev,
+					struct arizona *arizona,
 					struct regulator_config *config,
 					const struct regulator_desc *desc)
 {
@@ -213,7 +214,7 @@ static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
 	if (np) {
 		config->of_node = np;
 
-		init_data = of_get_regulator_init_data(arizona->dev, np, desc);
+		init_data = of_get_regulator_init_data(dev, np, desc);
 
 		if (init_data) {
 			init_data->consumer_supplies = &micsupp->supply;
@@ -268,8 +269,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
 
 	if (IS_ENABLED(CONFIG_OF)) {
 		if (!dev_get_platdata(arizona->dev)) {
-			ret = arizona_micsupp_of_get_pdata(arizona, &config,
-							   desc);
+			ret = arizona_micsupp_of_get_pdata(&pdev->dev, arizona,
+							   &config, desc);
 			if (ret < 0)
 				return ret;
 		}
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 2/8] regulator: arizona-ldo1: Avoid potential memory leak reading init_data
From: Charles Keepax @ 2017-03-28 14:14 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, patches, lgirdwood,
	linux-kernel, robh+dt, lee.jones
In-Reply-To: <1490710484-25277-1-git-send-email-ckeepax@opensource.wolfsonmicro.com>

The device argument passed to of_get_regulator_init_data is used to
do some devres memory allocation. Currently the driver passes the MFD
device pointer to this function, this could result in the init_data
allocation being leaked if the regulator is unbound but the MFD isn't.

Correct this issue by correctly passing the local platform device.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

New patch in the series since v1.

 drivers/regulator/arizona-ldo1.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index e76d094..b726fa1 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -186,7 +186,8 @@ static const struct regulator_init_data arizona_ldo1_wm5110 = {
 	.num_consumer_supplies = 1,
 };
 
-static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
+static int arizona_ldo1_of_get_pdata(struct device *dev,
+				     struct arizona *arizona,
 				     struct regulator_config *config,
 				     const struct regulator_desc *desc)
 {
@@ -212,8 +213,7 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
 	if (init_node) {
 		config->of_node = init_node;
 
-		init_data = of_get_regulator_init_data(arizona->dev, init_node,
-						       desc);
+		init_data = of_get_regulator_init_data(dev, init_node, desc);
 
 		if (init_data) {
 			init_data->consumer_supplies = &ldo1->supply;
@@ -283,7 +283,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
 
 	if (IS_ENABLED(CONFIG_OF)) {
 		if (!dev_get_platdata(arizona->dev)) {
-			ret = arizona_ldo1_of_get_pdata(arizona, &config, desc);
+			ret = arizona_ldo1_of_get_pdata(&pdev->dev, arizona,
+							&config, desc);
 			if (ret < 0)
 				return ret;
 		}
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 3/8] MAINTAINERS: Add missing regulator regex for Wolfson Arizona parts
From: Charles Keepax @ 2017-03-28 14:14 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, patches, lgirdwood,
	linux-kernel, robh+dt, lee.jones
In-Reply-To: <1490710484-25277-1-git-send-email-ckeepax@opensource.wolfsonmicro.com>

The maintainers entry for the Wolfson parts seems to be missing
an entry that covers the Arizona regulator drivers, correct this by
adding one.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

New patch in the series since v1.

 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c265a5f..c35e0ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13616,6 +13616,7 @@ F:	drivers/mfd/cs47l24*
 F:	drivers/power/supply/wm83*.c
 F:	drivers/rtc/rtc-wm83*.c
 F:	drivers/regulator/wm8*.c
+F:	drivers/regulator/arizona*
 F:	drivers/video/backlight/wm83*_bl.c
 F:	drivers/watchdog/wm83*_wdt.c
 F:	include/linux/mfd/arizona/
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 4/8] regulator: helpers: Add regmap set_soft_start helper
From: Charles Keepax @ 2017-03-28 14:14 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, patches, lgirdwood,
	linux-kernel, robh+dt, lee.jones
In-Reply-To: <1490710484-25277-1-git-send-email-ckeepax@opensource.wolfsonmicro.com>

Add a helper function regulator_set_soft_start_regmap to allow regmap
based regulators to easily enable soft start.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

Changes since v1:
 - Added documentation for the new regulator_desc fields to the kernel doc.

 drivers/regulator/helpers.c      | 18 ++++++++++++++++++
 include/linux/regulator/driver.h |  8 ++++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c
index 379cdac..a75e7da 100644
--- a/drivers/regulator/helpers.c
+++ b/drivers/regulator/helpers.c
@@ -446,6 +446,24 @@ int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
 EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
 
 /**
+ * regulator_set_soft_start_regmap - Default set_soft_start() using regmap
+ *
+ * @rdev: device to operate on.
+ */
+int regulator_set_soft_start_regmap(struct regulator_dev *rdev)
+{
+	unsigned int val;
+
+	val = rdev->desc->soft_start_val_on;
+	if (!val)
+		val = rdev->desc->soft_start_mask;
+
+	return regmap_update_bits(rdev->regmap, rdev->desc->soft_start_reg,
+				  rdev->desc->soft_start_mask, val);
+}
+EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);
+
+/**
  * regulator_get_bypass_regmap - Default get_bypass() using regmap
  *
  * @rdev: device to operate on.
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index dac8e7b1..1054c03 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -292,6 +292,10 @@ enum regulator_type {
  *			   set_active_discharge
  * @active_discharge_reg: Register for control when using regmap
  *			  set_active_discharge
+ * @soft_start_reg: Register for control when using regmap set_soft_start
+ * @soft_start_mask: Mask for control when using regmap set_soft_start
+ * @soft_start_val_on: Enabling value for control when using regmap
+ *                     set_soft_start
  *
  * @enable_time: Time taken for initial enable of regulator (in uS).
  * @off_on_delay: guard time (in uS), before re-enabling a regulator
@@ -345,6 +349,9 @@ struct regulator_desc {
 	unsigned int active_discharge_off;
 	unsigned int active_discharge_mask;
 	unsigned int active_discharge_reg;
+	unsigned int soft_start_reg;
+	unsigned int soft_start_mask;
+	unsigned int soft_start_val_on;
 
 	unsigned int enable_time;
 
@@ -476,6 +483,7 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
 				   unsigned int new_selector);
 int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable);
 int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable);
+int regulator_set_soft_start_regmap(struct regulator_dev *rdev);
 
 int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
 					  bool enable);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 5/8] regulator: helpers: Add regmap set_pull_down helper
From: Charles Keepax @ 2017-03-28 14:14 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, patches, lgirdwood,
	linux-kernel, robh+dt, lee.jones
In-Reply-To: <1490710484-25277-1-git-send-email-ckeepax@opensource.wolfsonmicro.com>

Add a helper function regulator_set_pull_down_regmap to allow regmap
based regulators to easily enable pull down.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

Turns out I don't actually need this patch for the series, but since I
had gone to the effort of writing the code anyway, thought I might as
well keep it in. Will be useful if someone does want to use a pull down
on a regmap regulators and it is has been pretty well tested here.

Changes since v1:
 - Added documentation for the new regulator_desc fields to the kernel doc.

 drivers/regulator/helpers.c      | 18 ++++++++++++++++++
 include/linux/regulator/driver.h |  8 ++++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c
index a75e7da..2ae7c3a 100644
--- a/drivers/regulator/helpers.c
+++ b/drivers/regulator/helpers.c
@@ -464,6 +464,24 @@ int regulator_set_soft_start_regmap(struct regulator_dev *rdev)
 EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);
 
 /**
+ * regulator_set_pull_down_regmap - Default set_pull_down() using regmap
+ *
+ * @rdev: device to operate on.
+ */
+int regulator_set_pull_down_regmap(struct regulator_dev *rdev)
+{
+	unsigned int val;
+
+	val = rdev->desc->pull_down_val_on;
+	if (!val)
+		val = rdev->desc->pull_down_mask;
+
+	return regmap_update_bits(rdev->regmap, rdev->desc->pull_down_reg,
+				  rdev->desc->pull_down_mask, val);
+}
+EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap);
+
+/**
  * regulator_get_bypass_regmap - Default get_bypass() using regmap
  *
  * @rdev: device to operate on.
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 1054c03..8a9078d 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -296,6 +296,10 @@ enum regulator_type {
  * @soft_start_mask: Mask for control when using regmap set_soft_start
  * @soft_start_val_on: Enabling value for control when using regmap
  *                     set_soft_start
+ * @pull_down_reg: Register for control when using regmap set_pull_down
+ * @pull_down_mask: Mask for control when using regmap set_pull_down
+ * @pull_down_val_on: Enabling value for control when using regmap
+ *                     set_pull_down
  *
  * @enable_time: Time taken for initial enable of regulator (in uS).
  * @off_on_delay: guard time (in uS), before re-enabling a regulator
@@ -352,6 +356,9 @@ struct regulator_desc {
 	unsigned int soft_start_reg;
 	unsigned int soft_start_mask;
 	unsigned int soft_start_val_on;
+	unsigned int pull_down_reg;
+	unsigned int pull_down_mask;
+	unsigned int pull_down_val_on;
 
 	unsigned int enable_time;
 
@@ -484,6 +491,7 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
 int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable);
 int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable);
 int regulator_set_soft_start_regmap(struct regulator_dev *rdev);
+int regulator_set_pull_down_regmap(struct regulator_dev *rdev);
 
 int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
 					  bool enable);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 6/8] regulator: arizona-micbias: Add regulator driver for Arizona micbiases
From: Charles Keepax @ 2017-03-28 14:14 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, patches, lgirdwood,
	linux-kernel, robh+dt, lee.jones
In-Reply-To: <1490710484-25277-1-git-send-email-ckeepax@opensource.wolfsonmicro.com>

Add a driver for controlling the micbias regulators on the Arizona class
audio CODECs. This will replace earlier fixed support that initialised
the micbias's with fixed settings from platform data, although that
platform data can still be used to configure the constraints on this new
regulator.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

Changes since v1:
 - Use active_discharge rather than pull_down as that is what the
   regulator actually does.
 - Pass the micbias device rather than the arizona device to
   of_get_regulator_init_data to avoid leaking init_data
 - Update the pdata to use an actual regulator_init_data
 - Tidy up the code to make it a little easier to follow

 drivers/regulator/Makefile          |   2 +-
 drivers/regulator/arizona-micbias.c | 228 ++++++++++++++++++++++++++++++++++++
 include/linux/mfd/arizona/pdata.h   |   6 +-
 3 files changed, 231 insertions(+), 5 deletions(-)
 create mode 100644 drivers/regulator/arizona-micbias.c

diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index ef7725e..b670e87 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -19,7 +19,7 @@ obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o
 obj-$(CONFIG_REGULATOR_ACT8945A) += act8945a-regulator.o
 obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
 obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
-obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
+obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o arizona-micbias.o
 obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
 obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
 obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
diff --git a/drivers/regulator/arizona-micbias.c b/drivers/regulator/arizona-micbias.c
new file mode 100644
index 0000000..622e659
--- /dev/null
+++ b/drivers/regulator/arizona-micbias.c
@@ -0,0 +1,228 @@
+/*
+ * arizona-micbias.c  --  Microphone bias supplies for Arizona devices
+ *
+ * Copyright 2017 Cirrus Logic Inc.
+ *
+ * Author: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/arizona/core.h>
+#include <linux/mfd/arizona/pdata.h>
+#include <linux/mfd/arizona/registers.h>
+
+#define ARIZONA_MICBIAS_MAX_SELECTOR 0xD
+
+struct arizona_micbias_priv {
+	int id;
+	struct arizona *arizona;
+
+	struct device_node *np;
+	struct regulator_desc desc;
+	struct regulator_consumer_supply supply;
+	struct regulator_init_data *init_data;
+
+	struct regulator_dev *regulator;
+};
+
+static const struct regulator_ops arizona_micbias_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_linear,
+	.map_voltage = regulator_map_voltage_linear,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_bypass = regulator_get_bypass_regmap,
+	.set_bypass = regulator_set_bypass_regmap,
+	.set_soft_start = regulator_set_soft_start_regmap,
+	.set_active_discharge = regulator_set_active_discharge_regmap,
+};
+
+static const struct regulator_desc arizona_micbias_desc_tmpl = {
+	.supply_name = "MICVDD",
+	.type = REGULATOR_VOLTAGE,
+	.ops = &arizona_micbias_ops,
+
+	.min_uV = 1500000,
+	.uV_step = 100000,
+	.n_voltages = ARIZONA_MICBIAS_MAX_SELECTOR + 1,
+
+	.vsel_reg = ARIZONA_MIC_BIAS_CTRL_1,
+	.vsel_mask = ARIZONA_MICB1_LVL_MASK,
+	.enable_reg = ARIZONA_MIC_BIAS_CTRL_1,
+	.enable_mask = ARIZONA_MICB1_ENA,
+	.bypass_reg = ARIZONA_MIC_BIAS_CTRL_1,
+	.bypass_mask = ARIZONA_MICB1_BYPASS,
+	.soft_start_reg = ARIZONA_MIC_BIAS_CTRL_1,
+	.soft_start_mask = ARIZONA_MICB1_RATE,
+	.active_discharge_reg = ARIZONA_MIC_BIAS_CTRL_1,
+	.active_discharge_mask = ARIZONA_MICB1_DISCH,
+	.active_discharge_on = ARIZONA_MICB1_DISCH,
+
+	.owner = THIS_MODULE,
+};
+
+static const struct regulator_init_data arizona_micbias_tmpl = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
+				  REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_BYPASS,
+		.min_uV = 1500000,
+		.max_uV = 2800000,
+	},
+};
+
+static int arizona_micbias_of_get_pdata(struct device *dev,
+					struct device_node *np,
+					struct arizona_micbias_priv *micbias)
+{
+	struct arizona *arizona = micbias->arizona;
+	struct arizona_micbias *pdata = &arizona->pdata.micbias[micbias->id];
+
+	micbias->np = of_get_child_by_name(np, micbias->desc.name);
+	if (micbias->np) {
+		micbias->init_data = of_get_regulator_init_data(dev,
+								micbias->np,
+								&micbias->desc);
+
+		pdata->ext_cap = of_property_read_bool(micbias->np,
+						       "wlf,ext-cap");
+	}
+
+	return 0;
+}
+
+static int arizona_micbias_init_pdata(struct device *dev,
+				      struct arizona_micbias_priv *micbias)
+{
+	struct arizona *arizona = micbias->arizona;
+	struct arizona_micbias *pdata = &arizona->pdata.micbias[micbias->id];
+	int ret;
+
+	if (pdata->init_data)
+		return 0;
+
+	if (IS_ENABLED(CONFIG_OF)) {
+		struct device_node *np = arizona->dev->of_node;
+
+		ret = arizona_micbias_of_get_pdata(dev, np, micbias);
+		if (ret < 0) {
+			dev_err(dev, "Failed to parse DT: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (!micbias->init_data) {
+		micbias->init_data = devm_kmemdup(dev,
+						  &arizona_micbias_tmpl,
+						  sizeof(arizona_micbias_tmpl),
+						  GFP_KERNEL);
+		if (!micbias->init_data)
+			return -ENOMEM;
+	}
+
+	micbias->supply.supply = micbias->desc.name;
+	micbias->supply.dev_name = dev_name(arizona->dev);
+
+	micbias->init_data->consumer_supplies = &micbias->supply;
+	micbias->init_data->num_consumer_supplies = 1;
+
+	pdata->init_data = micbias->init_data;
+
+	return 0;
+}
+
+static int arizona_micbias_probe(struct platform_device *pdev)
+{
+	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
+	int id = pdev->id;
+	struct arizona_micbias *pdata = &arizona->pdata.micbias[id];
+	struct arizona_micbias_priv *micbias;
+	struct regulator_config config = { };
+	unsigned int val;
+	int ret;
+
+	micbias = devm_kzalloc(&pdev->dev, sizeof(*micbias), GFP_KERNEL);
+	if (micbias == NULL)
+		return -ENOMEM;
+
+	micbias->id = id;
+	micbias->arizona = arizona;
+
+	micbias->desc = arizona_micbias_desc_tmpl;
+	micbias->desc.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+					    "MICBIAS%d", id + 1);
+	micbias->desc.vsel_reg += id;
+	micbias->desc.enable_reg += id;
+	micbias->desc.bypass_reg += id;
+	micbias->desc.soft_start_reg += id;
+	micbias->desc.pull_down_reg += id;
+
+	ret = arizona_micbias_init_pdata(&pdev->dev, micbias);
+	if (ret)
+		return ret;
+
+	if (pdata->ext_cap)
+		val = ARIZONA_MICB1_EXT_CAP;
+	else
+		val = 0;
+
+	/*
+	 * The core expects the regulator to have bypass disabled by default
+	 * so clear it, whilst we set the external cap.
+	 */
+	regmap_update_bits(arizona->regmap, ARIZONA_MIC_BIAS_CTRL_1 + id,
+			   ARIZONA_MICB1_EXT_CAP | ARIZONA_MICB1_BYPASS, val);
+
+	config.dev = arizona->dev;
+	config.regmap = arizona->regmap;
+	config.of_node = micbias->np;
+	config.init_data = pdata->init_data;
+	config.driver_data = micbias;
+
+	micbias->regulator = devm_regulator_register(&pdev->dev,
+						     &micbias->desc,
+						     &config);
+
+	of_node_put(config.of_node);
+
+	if (IS_ERR(micbias->regulator)) {
+		ret = PTR_ERR(micbias->regulator);
+		dev_err(arizona->dev, "Failed to register %s supply: %d\n",
+			micbias->desc.name, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct platform_driver arizona_micbias_driver = {
+	.probe = arizona_micbias_probe,
+	.driver		= {
+		.name	= "arizona-micbias",
+	},
+};
+
+module_platform_driver(arizona_micbias_driver);
+
+/* Module information */
+MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("Arizona microphone bias supply driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:arizona-micbias");
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 64faeef..89a3512 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -56,11 +56,9 @@
 struct regulator_init_data;
 
 struct arizona_micbias {
-	int mV;                    /** Regulated voltage */
+	/* Regulator configuration */
+	const struct regulator_init_data *init_data;
 	unsigned int ext_cap:1;    /** External capacitor fitted */
-	unsigned int discharge:1;  /** Actively discharge */
-	unsigned int soft_start:1; /** Disable aggressive startup ramp rate */
-	unsigned int bypass:1;     /** Use bypass mode */
 };
 
 struct arizona_micd_config {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 7/8] regulator: arizona-micbias: Add description of micbias binding
From: Charles Keepax @ 2017-03-28 14:14 UTC (permalink / raw)
  To: broonie
  Cc: mark.rutland, devicetree, alsa-devel, patches, lgirdwood,
	linux-kernel, robh+dt, lee.jones
In-Reply-To: <1490710484-25277-1-git-send-email-ckeepax@opensource.wolfsonmicro.com>

Add the new micbias regulators into the Arizona regulator binding
document.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Rob Herring <robh@kernel.org>
---

No changes since v1.

 Documentation/devicetree/bindings/regulator/arizona-regulator.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
index 443564d..68a13d5 100644
--- a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
@@ -15,3 +15,9 @@ Optional subnodes:
     Documentation/devicetree/bindings/regulator/regulator.txt
   - micvdd : Initial data for the MICVDD regulator, as covered in
     Documentation/devicetree/bindings/regulator/regulator.txt
+
+  - MICBIASx : Initial data for the MICBIAS regulators, as covered in
+    Documentation/devicetree/bindings/regulator/regulator.txt but the
+    following additional properties are also supported:
+      - wlf,ext-cap : Specifies if the MICBIAS has external decoupling
+        capacitors attached.
-- 
2.1.4

^ permalink raw reply related


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