Devicetree
 help / color / mirror / Atom feed
* [PATCH 2/5] clk: sunxi-ng: add support for V3s CCU
From: Icenowy Zheng @ 2017-01-03 15:16 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Stephen Boyd, Linus Walleij
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170103151629.19447-1-icenowy-ymACFijhrKM@public.gmane.org>

V3s has a similar but cut-down CCU to H3.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 drivers/clk/sunxi-ng/Kconfig              |  11 +
 drivers/clk/sunxi-ng/Makefile             |   1 +
 drivers/clk/sunxi-ng/ccu-sun8i-v3s.c      | 590 ++++++++++++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun8i-v3s.h      |  63 ++++
 include/dt-bindings/clock/sun8i-v3s-ccu.h | 107 ++++++
 include/dt-bindings/reset/sun8i-v3s-ccu.h |  78 ++++
 6 files changed, 850 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
 create mode 100644 include/dt-bindings/clock/sun8i-v3s-ccu.h
 create mode 100644 include/dt-bindings/reset/sun8i-v3s-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 8454c6e3dd65..1ca48255802f 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -109,4 +109,15 @@ config SUN8I_H3_CCU
 	select SUNXI_CCU_PHASE
 	default MACH_SUN8I
 
+config SUN8I_V3S_CCU
+	bool "Support for the Allwinner V3s CCU"
+	select SUNXI_CCU_DIV
+	select SUNXI_CCU_NK
+	select SUNXI_CCU_NKM
+	select SUNXI_CCU_NKMP
+	select SUNXI_CCU_NM
+	select SUNXI_CCU_MP
+	select SUNXI_CCU_PHASE
+	default MACH_SUN8I
+
 endif
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 24fbc6e5deb8..d1cd81a0f112 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
 obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
 obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
 obj-$(CONFIG_SUN8I_H3_CCU)	+= ccu-sun8i-h3.o
+obj-$(CONFIG_SUN8I_V3S_CCU)	+= ccu-sun8i-v3s.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
new file mode 100644
index 000000000000..e569af9338c2
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * Based on ccu-sun8i-h3.c, which is:
+ * Copyright (c) 2016 Maxime Ripard. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun8i-v3s.h"
+
+static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
+				     "osc24M", 0x000,
+				     8, 5,	/* N */
+				     4, 2,	/* K */
+				     0, 2,	/* M */
+				     16, 2,	/* P */
+				     BIT(31),	/* gate */
+				     BIT(28),	/* lock */
+				     0);
+
+/*
+ * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
+ * the base (2x, 4x and 8x), and one variable divider (the one true
+ * pll audio).
+ *
+ * We don't have any need for the variable divider for now, so we just
+ * hardcode it to match with the clock names
+ */
+#define SUN8I_V3S_PLL_AUDIO_REG	0x008
+
+static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
+				   "osc24M", 0x008,
+				   8, 7,	/* N */
+				   0, 5,	/* M */
+				   BIT(31),	/* gate */
+				   BIT(28),	/* lock */
+				   0);
+
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
+					"osc24M", 0x0010,
+					8, 7,		/* N */
+					0, 4,		/* M */
+					BIT(24),	/* frac enable */
+					BIT(25),	/* frac select */
+					270000000,	/* frac rate 0 */
+					297000000,	/* frac rate 1 */
+					BIT(31),	/* gate */
+					BIT(28),	/* lock */
+					0);
+
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
+					"osc24M", 0x0018,
+					8, 7,		/* N */
+					0, 4,		/* M */
+					BIT(24),	/* frac enable */
+					BIT(25),	/* frac select */
+					270000000,	/* frac rate 0 */
+					297000000,	/* frac rate 1 */
+					BIT(31),	/* gate */
+					BIT(28),	/* lock */
+					0);
+
+static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
+				    "osc24M", 0x020,
+				    8, 5,	/* N */
+				    4, 2,	/* K */
+				    0, 2,	/* M */
+				    BIT(31),	/* gate */
+				    BIT(28),	/* lock */
+				    0);
+
+static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
+					   "osc24M", 0x028,
+					   8, 5,	/* N */
+					   4, 2,	/* K */
+					   BIT(31),	/* gate */
+					   BIT(28),	/* lock */
+					   2,		/* post-div */
+					   0);
+
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_isp_clk, "pll-isp",
+					"osc24M", 0x002c,
+					8, 7,		/* N */
+					0, 4,		/* M */
+					BIT(24),	/* frac enable */
+					BIT(25),	/* frac select */
+					270000000,	/* frac rate 0 */
+					297000000,	/* frac rate 1 */
+					BIT(31),	/* gate */
+					BIT(28),	/* lock */
+					0);
+
+static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
+					   "osc24M", 0x044,
+					   8, 5,	/* N */
+					   4, 2,	/* K */
+					   BIT(31),	/* gate */
+					   BIT(28),	/* lock */
+					   2,		/* post-div */
+					   0);
+
+static const char * const cpu_parents[] = { "osc32k", "osc24M",
+					     "pll-cpu" , "pll-cpu" };
+static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
+		     0x050, 16, 2, CLK_IS_CRITICAL);
+
+static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0);
+
+static const char * const ahb1_parents[] = { "osc32k", "osc24M",
+					     "axi" , "pll-periph0" };
+static struct ccu_div ahb1_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.mux		= {
+		.shift	= 12,
+		.width	= 2,
+
+		.variable_prediv	= {
+			.index	= 3,
+			.shift	= 6,
+			.width	= 2,
+		},
+	},
+
+	.common		= {
+		.reg		= 0x054,
+		.features	= CCU_FEATURE_VARIABLE_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS("ahb1",
+						      ahb1_parents,
+						      &ccu_div_ops,
+						      0),
+	},
+};
+
+static struct clk_div_table apb1_div_table[] = {
+	{ .val = 0, .div = 2 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 8 },
+	{ /* Sentinel */ },
+};
+static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
+			   0x054, 8, 2, apb1_div_table, 0);
+
+static const char * const apb2_parents[] = { "osc32k", "osc24M",
+					     "pll-periph0" , "pll-periph0" };
+static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
+			     0, 5,	/* M */
+			     16, 2,	/* P */
+			     24, 2,	/* mux */
+			     0);
+
+static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" };
+static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
+	{ .index = 1, .div = 2 },
+};
+static struct ccu_mux ahb2_clk = {
+	.mux		= {
+		.shift	= 0,
+		.width	= 1,
+		.fixed_predivs	= ahb2_fixed_predivs,
+		.n_predivs	= ARRAY_SIZE(ahb2_fixed_predivs),
+	},
+
+	.common		= {
+		.reg		= 0x05c,
+		.features	= CCU_FEATURE_FIXED_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS("ahb2",
+						      ahb2_parents,
+						      &ccu_mux_ops,
+						      0),
+	},
+};
+
+static SUNXI_CCU_GATE(bus_ce_clk,	"bus-ce",	"ahb1",
+		      0x060, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_dma_clk,	"bus-dma",	"ahb1",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(bus_mmc0_clk,	"bus-mmc0",	"ahb1",
+		      0x060, BIT(8), 0);
+static SUNXI_CCU_GATE(bus_mmc1_clk,	"bus-mmc1",	"ahb1",
+		      0x060, BIT(9), 0);
+static SUNXI_CCU_GATE(bus_mmc2_clk,	"bus-mmc2",	"ahb1",
+		      0x060, BIT(10), 0);
+static SUNXI_CCU_GATE(bus_dram_clk,	"bus-dram",	"ahb1",
+		      0x060, BIT(14), 0);
+static SUNXI_CCU_GATE(bus_emac_clk,	"bus-emac",	"ahb2",
+		      0x060, BIT(17), 0);
+static SUNXI_CCU_GATE(bus_hstimer_clk,	"bus-hstimer",	"ahb1",
+		      0x060, BIT(19), 0);
+static SUNXI_CCU_GATE(bus_spi0_clk,	"bus-spi0",	"ahb1",
+		      0x060, BIT(20), 0);
+static SUNXI_CCU_GATE(bus_otg_clk,	"bus-otg",	"ahb1",
+		      0x060, BIT(24), 0);
+static SUNXI_CCU_GATE(bus_ehci0_clk,	"bus-ehci0",	"ahb1",
+		      0x060, BIT(26), 0);
+static SUNXI_CCU_GATE(bus_ohci0_clk,	"bus-ohci0",	"ahb1",
+		      0x060, BIT(29), 0);
+
+static SUNXI_CCU_GATE(bus_ve_clk,	"bus-ve",	"ahb1",
+		      0x064, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_tcon0_clk,	"bus-tcon0",	"ahb1",
+		      0x064, BIT(4), 0);
+static SUNXI_CCU_GATE(bus_csi_clk,	"bus-csi",	"ahb1",
+		      0x064, BIT(8), 0);
+static SUNXI_CCU_GATE(bus_de_clk,	"bus-de",	"ahb1",
+		      0x064, BIT(12), 0);
+
+static SUNXI_CCU_GATE(bus_codec_clk,	"bus-codec",	"apb1",
+		      0x068, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_pio_clk,	"bus-pio",	"apb1",
+		      0x068, BIT(5), 0);
+
+static SUNXI_CCU_GATE(bus_i2c0_clk,	"bus-i2c0",	"apb2",
+		      0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c1_clk,	"bus-i2c1",	"apb2",
+		      0x06c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_uart0_clk,	"bus-uart0",	"apb2",
+		      0x06c, BIT(16), 0);
+static SUNXI_CCU_GATE(bus_uart1_clk,	"bus-uart1",	"apb2",
+		      0x06c, BIT(17), 0);
+static SUNXI_CCU_GATE(bus_uart2_clk,	"bus-uart2",	"apb2",
+		      0x06c, BIT(18), 0);
+
+static SUNXI_CCU_GATE(bus_ephy_clk,	"bus-ephy",	"ahb1",
+		      0x070, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_dbg_clk,	"bus-dbg",	"ahb1",
+		      0x070, BIT(7), 0);
+
+static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
+						     "pll-periph1" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
+		       0x088, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
+		       0x088, 8, 3, 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
+		       0x08c, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
+		       0x08c, 8, 3, 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
+		       0x090, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
+		       0x090, 8, 3, 0);
+
+static const char * const ce_parents[] = { "osc24M", "pll-periph0", };
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x09c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(usb_phy0_clk,	"usb-phy0",	"osc24M",
+		      0x0cc, BIT(8), 0);
+static SUNXI_CCU_GATE(usb_ohci0_clk,	"usb-ohci0",	"osc24M",
+		      0x0cc, BIT(16), 0);
+
+static const char * const dram_parents[] = { "pll-ddr", "pll-periph0-2x" };
+static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
+			    0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE(dram_ve_clk,	"dram-ve",	"dram",
+		      0x100, BIT(0), 0);
+static SUNXI_CCU_GATE(dram_csi_clk,	"dram-csi",	"dram",
+		      0x100, BIT(1), 0);
+static SUNXI_CCU_GATE(dram_ehci_clk,	"dram-ehci",	"dram",
+		      0x100, BIT(17), 0);
+static SUNXI_CCU_GATE(dram_ohci_clk,	"dram-ohci",	"dram",
+		      0x100, BIT(18), 0);
+
+static const char * const de_parents[] = { "pll-video", "pll-periph0" };
+static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
+				 0x104, 0, 4, 24, 2, BIT(31), 0);
+
+static const char * const tcon_parents[] = { "pll-video" };
+static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
+				 0x118, 0, 4, 24, 3, BIT(31), 0);
+
+static SUNXI_CCU_GATE(csi_misc_clk,	"csi-misc",	"osc24M",
+		      0x130, BIT(31), 0);
+
+static const char * const csi_mclk_parents[] = { "osc24M", "pll-video",
+						 "pll-periph0", "pll-periph1" };
+static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents,
+				 0x130, 0, 5, 8, 3, BIT(15), 0);
+
+static const char * const csi1_sclk_parents[] = { "pll-video", "pll-isp" };
+static SUNXI_CCU_M_WITH_MUX_GATE(csi1_sclk_clk, "csi-sclk", csi1_sclk_parents,
+				 0x134, 16, 4, 24, 3, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi-mclk", csi_mclk_parents,
+				 0x134, 0, 5, 8, 3, BIT(15), 0);
+
+static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
+			     0x13c, 16, 3, BIT(31), 0);
+
+static SUNXI_CCU_GATE(ac_dig_clk,	"ac-dig",	"pll-audio",
+		      0x140, BIT(31), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE(avs_clk,		"avs",		"osc24M",
+		      0x144, BIT(31), 0);
+
+static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x", "pll-ddr" };
+static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
+				 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
+
+static const char * const mipi_csi_parents[] = { "pll-video", "pll-periph0",
+						 "pll-isp" };
+static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_clk, "mipi-csi", mipi_csi_parents,
+			     0x16c, 0, 3, 24, 2, BIT(31), 0);
+
+static struct ccu_common *sun8i_v3s_ccu_clks[] = {
+	&pll_cpu_clk.common,
+	&pll_audio_base_clk.common,
+	&pll_video_clk.common,
+	&pll_ve_clk.common,
+	&pll_ddr_clk.common,
+	&pll_periph0_clk.common,
+	&pll_isp_clk.common,
+	&pll_periph1_clk.common,
+	&cpu_clk.common,
+	&axi_clk.common,
+	&ahb1_clk.common,
+	&apb1_clk.common,
+	&apb2_clk.common,
+	&ahb2_clk.common,
+	&bus_ce_clk.common,
+	&bus_dma_clk.common,
+	&bus_mmc0_clk.common,
+	&bus_mmc1_clk.common,
+	&bus_mmc2_clk.common,
+	&bus_dram_clk.common,
+	&bus_emac_clk.common,
+	&bus_hstimer_clk.common,
+	&bus_spi0_clk.common,
+	&bus_otg_clk.common,
+	&bus_ehci0_clk.common,
+	&bus_ohci0_clk.common,
+	&bus_ve_clk.common,
+	&bus_tcon0_clk.common,
+	&bus_csi_clk.common,
+	&bus_de_clk.common,
+	&bus_codec_clk.common,
+	&bus_pio_clk.common,
+	&bus_i2c0_clk.common,
+	&bus_i2c1_clk.common,
+	&bus_uart0_clk.common,
+	&bus_uart1_clk.common,
+	&bus_uart2_clk.common,
+	&bus_ephy_clk.common,
+	&bus_dbg_clk.common,
+	&mmc0_clk.common,
+	&mmc0_sample_clk.common,
+	&mmc0_output_clk.common,
+	&mmc1_clk.common,
+	&mmc1_sample_clk.common,
+	&mmc1_output_clk.common,
+	&mmc2_clk.common,
+	&mmc2_sample_clk.common,
+	&mmc2_output_clk.common,
+	&ce_clk.common,
+	&spi0_clk.common,
+	&usb_phy0_clk.common,
+	&usb_ohci0_clk.common,
+	&dram_clk.common,
+	&dram_ve_clk.common,
+	&dram_csi_clk.common,
+	&dram_ohci_clk.common,
+	&dram_ehci_clk.common,
+	&de_clk.common,
+	&tcon_clk.common,
+	&csi_misc_clk.common,
+	&csi0_mclk_clk.common,
+	&csi1_sclk_clk.common,
+	&csi1_mclk_clk.common,
+	&ve_clk.common,
+	&ac_dig_clk.common,
+	&avs_clk.common,
+	&mbus_clk.common,
+	&mipi_csi_clk.common,
+};
+
+/* We hardcode the divider to 4 for now */
+static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
+			"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
+			"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
+			"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
+			"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
+			"pll-periph0", 1, 2, 0);
+
+static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
+	.hws	= {
+		[CLK_PLL_CPU]		= &pll_cpu_clk.common.hw,
+		[CLK_PLL_AUDIO_BASE]	= &pll_audio_base_clk.common.hw,
+		[CLK_PLL_AUDIO]		= &pll_audio_clk.hw,
+		[CLK_PLL_AUDIO_2X]	= &pll_audio_2x_clk.hw,
+		[CLK_PLL_AUDIO_4X]	= &pll_audio_4x_clk.hw,
+		[CLK_PLL_AUDIO_8X]	= &pll_audio_8x_clk.hw,
+		[CLK_PLL_VIDEO]		= &pll_video_clk.common.hw,
+		[CLK_PLL_VE]		= &pll_ve_clk.common.hw,
+		[CLK_PLL_DDR]		= &pll_ddr_clk.common.hw,
+		[CLK_PLL_PERIPH0]	= &pll_periph0_clk.common.hw,
+		[CLK_PLL_PERIPH0_2X]	= &pll_periph0_2x_clk.hw,
+		[CLK_PLL_ISP]		= &pll_isp_clk.common.hw,
+		[CLK_PLL_PERIPH1]	= &pll_periph1_clk.common.hw,
+		[CLK_CPU]		= &cpu_clk.common.hw,
+		[CLK_AXI]		= &axi_clk.common.hw,
+		[CLK_AHB1]		= &ahb1_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_APB2]		= &apb2_clk.common.hw,
+		[CLK_AHB2]		= &ahb2_clk.common.hw,
+		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
+		[CLK_BUS_DMA]		= &bus_dma_clk.common.hw,
+		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
+		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
+		[CLK_BUS_MMC2]		= &bus_mmc2_clk.common.hw,
+		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
+		[CLK_BUS_EMAC]		= &bus_emac_clk.common.hw,
+		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
+		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
+		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
+		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
+		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
+		[CLK_BUS_VE]		= &bus_ve_clk.common.hw,
+		[CLK_BUS_TCON0]		= &bus_tcon0_clk.common.hw,
+		[CLK_BUS_CSI]		= &bus_csi_clk.common.hw,
+		[CLK_BUS_DE]		= &bus_de_clk.common.hw,
+		[CLK_BUS_CODEC]		= &bus_codec_clk.common.hw,
+		[CLK_BUS_PIO]		= &bus_pio_clk.common.hw,
+		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
+		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
+		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
+		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
+		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
+		[CLK_BUS_EPHY]		= &bus_ephy_clk.common.hw,
+		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC0_SAMPLE]	= &mmc0_sample_clk.common.hw,
+		[CLK_MMC0_OUTPUT]	= &mmc0_output_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_MMC1_SAMPLE]	= &mmc1_sample_clk.common.hw,
+		[CLK_MMC1_OUTPUT]	= &mmc1_output_clk.common.hw,
+		[CLK_CE]		= &ce_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
+		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
+		[CLK_DRAM]		= &dram_clk.common.hw,
+		[CLK_DRAM_VE]		= &dram_ve_clk.common.hw,
+		[CLK_DRAM_CSI]		= &dram_csi_clk.common.hw,
+		[CLK_DRAM_EHCI]		= &dram_ehci_clk.common.hw,
+		[CLK_DRAM_OHCI]		= &dram_ohci_clk.common.hw,
+		[CLK_DE]		= &de_clk.common.hw,
+		[CLK_TCON0]		= &tcon_clk.common.hw,
+		[CLK_CSI_MISC]		= &csi_misc_clk.common.hw,
+		[CLK_CSI0_MCLK]		= &csi0_mclk_clk.common.hw,
+		[CLK_CSI1_SCLK]		= &csi1_sclk_clk.common.hw,
+		[CLK_CSI1_MCLK]		= &csi1_mclk_clk.common.hw,
+		[CLK_VE]		= &ve_clk.common.hw,
+		[CLK_AC_DIG]		= &ac_dig_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_MBUS]		= &mbus_clk.common.hw,
+		[CLK_MIPI_CSI]		= &mipi_csi_clk.common.hw,
+	},
+	.num	= CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
+	[RST_USB_PHY0]		=  { 0x0cc, BIT(0) },
+
+	[RST_MBUS]		=  { 0x0fc, BIT(31) },
+
+	[RST_BUS_CE]		=  { 0x2c0, BIT(5) },
+	[RST_BUS_DMA]		=  { 0x2c0, BIT(6) },
+	[RST_BUS_MMC0]		=  { 0x2c0, BIT(8) },
+	[RST_BUS_MMC1]		=  { 0x2c0, BIT(9) },
+	[RST_BUS_MMC2]		=  { 0x2c0, BIT(10) },
+	[RST_BUS_DRAM]		=  { 0x2c0, BIT(14) },
+	[RST_BUS_EMAC]		=  { 0x2c0, BIT(17) },
+	[RST_BUS_HSTIMER]	=  { 0x2c0, BIT(19) },
+	[RST_BUS_SPI0]		=  { 0x2c0, BIT(20) },
+	[RST_BUS_OTG]		=  { 0x2c0, BIT(23) },
+	[RST_BUS_EHCI0]		=  { 0x2c0, BIT(26) },
+	[RST_BUS_OHCI0]		=  { 0x2c0, BIT(29) },
+
+	[RST_BUS_VE]		=  { 0x2c4, BIT(0) },
+	[RST_BUS_TCON0]		=  { 0x2c4, BIT(3) },
+	[RST_BUS_CSI]		=  { 0x2c4, BIT(8) },
+	[RST_BUS_DE]		=  { 0x2c4, BIT(12) },
+	[RST_BUS_DBG]		=  { 0x2c4, BIT(31) },
+
+	[RST_BUS_EPHY]		=  { 0x2c8, BIT(2) },
+
+	[RST_BUS_CODEC]		=  { 0x2d0, BIT(0) },
+
+	[RST_BUS_I2C0]		=  { 0x2d8, BIT(0) },
+	[RST_BUS_I2C1]		=  { 0x2d8, BIT(1) },
+	[RST_BUS_UART0]		=  { 0x2d8, BIT(16) },
+	[RST_BUS_UART1]		=  { 0x2d8, BIT(17) },
+	[RST_BUS_UART2]		=  { 0x2d8, BIT(18) },
+};
+
+static const struct sunxi_ccu_desc sun8i_v3s_ccu_desc = {
+	.ccu_clks	= sun8i_v3s_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun8i_v3s_ccu_clks),
+
+	.hw_clks	= &sun8i_v3s_hw_clks,
+
+	.resets		= sun8i_v3s_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun8i_v3s_ccu_resets),
+};
+
+static void __init sun8i_v3s_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+	u32 val;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%s: Could not map the clock registers\n",
+		       of_node_full_name(node));
+		return;
+	}
+
+	/* Force the PLL-Audio-1x divider to 4 */
+	val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
+	val &= ~GENMASK(19, 16);
+	writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG);
+
+	sunxi_ccu_probe(node, reg, &sun8i_v3s_ccu_desc);
+}
+CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
+	       sun8i_v3s_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
new file mode 100644
index 000000000000..77fee2a4888e
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ * 
+ * Based on ccu-sun8i-h3.h, which is:
+ * Copyright (c) 2016 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef _CCU_SUN8I_H3_H_
+#define _CCU_SUN8I_H3_H_
+
+#include <dt-bindings/clock/sun8i-v3s-ccu.h>
+#include <dt-bindings/reset/sun8i-v3s-ccu.h>
+
+#define CLK_PLL_CPU		0
+#define CLK_PLL_AUDIO_BASE	1
+#define CLK_PLL_AUDIO		2
+#define CLK_PLL_AUDIO_2X	3
+#define CLK_PLL_AUDIO_4X	4
+#define CLK_PLL_AUDIO_8X	5
+#define CLK_PLL_VIDEO		6
+#define CLK_PLL_VE		7
+#define CLK_PLL_DDR		8
+#define CLK_PLL_PERIPH0		9
+#define CLK_PLL_PERIPH0_2X	10
+#define CLK_PLL_ISP		11
+#define CLK_PLL_PERIPH1		12
+/* Reserve one number for not implemented and not used PLL_DDR1 */
+
+/* The CPU clock is exported */
+
+#define CLK_AXI			15
+#define CLK_AHB1		16
+#define CLK_APB1		17
+#define CLK_APB2		18
+#define CLK_AHB2		19
+
+/* All the bus gates are exported */
+
+/* The first bunch of module clocks are exported */
+
+#define CLK_DRAM		58
+
+/* All the DRAM gates are exported */
+
+/* Some more module clocks are exported */
+
+#define CLK_MBUS		72
+
+/* And the GPU module clock is exported */
+
+#define CLK_NUMBER		(CLK_MIPI_CSI + 1)
+
+#endif /* _CCU_SUN8I_H3_H_ */
diff --git a/include/dt-bindings/clock/sun8i-v3s-ccu.h b/include/dt-bindings/clock/sun8i-v3s-ccu.h
new file mode 100644
index 000000000000..c0d5d5599c87
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-v3s-ccu.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * Based on sun8i-h3-ccu.h, which is:
+ * Copyright (C) 2016 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ *     This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN8I_V3S_H_
+#define _DT_BINDINGS_CLK_SUN8I_V3S_H_
+
+#define CLK_CPU			14
+
+#define CLK_BUS_CE		20
+#define CLK_BUS_DMA		21
+#define CLK_BUS_MMC0		22
+#define CLK_BUS_MMC1		23
+#define CLK_BUS_MMC2		24
+#define CLK_BUS_DRAM		25
+#define CLK_BUS_EMAC		26
+#define CLK_BUS_HSTIMER		27
+#define CLK_BUS_SPI0		28
+#define CLK_BUS_OTG		29
+#define CLK_BUS_EHCI0		30
+#define CLK_BUS_OHCI0		31
+#define CLK_BUS_VE		32
+#define CLK_BUS_TCON0		33
+#define CLK_BUS_CSI		34
+#define CLK_BUS_DE		35
+#define CLK_BUS_CODEC		36
+#define CLK_BUS_PIO		37
+#define CLK_BUS_I2C0		38
+#define CLK_BUS_I2C1		39
+#define CLK_BUS_UART0		40
+#define CLK_BUS_UART1		41
+#define CLK_BUS_UART2		42
+#define CLK_BUS_EPHY		43
+#define CLK_BUS_DBG		44
+
+#define CLK_MMC0		45
+#define CLK_MMC0_SAMPLE		46
+#define CLK_MMC0_OUTPUT		47
+#define CLK_MMC1		48
+#define CLK_MMC1_SAMPLE		49
+#define CLK_MMC1_OUTPUT		50
+#define CLK_MMC2		51
+#define CLK_MMC2_SAMPLE		52
+#define CLK_MMC2_OUTPUT		53
+#define CLK_CE			54
+#define CLK_SPI0		55
+#define CLK_USB_PHY0		56
+#define CLK_USB_OHCI0		57
+
+#define CLK_DRAM_VE		59
+#define CLK_DRAM_CSI		60
+#define CLK_DRAM_EHCI		61
+#define CLK_DRAM_OHCI		62
+#define CLK_DE			63
+#define CLK_TCON0		64
+#define CLK_CSI_MISC		65
+#define CLK_CSI0_MCLK		66
+#define CLK_CSI1_SCLK		67
+#define CLK_CSI1_MCLK		68
+#define CLK_VE			69
+#define CLK_AC_DIG		70
+#define CLK_AVS			71
+
+#define CLK_MIPI_CSI		73
+
+#endif /* _DT_BINDINGS_CLK_SUN8I_V3S_H_ */
diff --git a/include/dt-bindings/reset/sun8i-v3s-ccu.h b/include/dt-bindings/reset/sun8i-v3s-ccu.h
new file mode 100644
index 000000000000..b58ef21a2e18
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-v3s-ccu.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * Based on sun8i-v3s-ccu.h, which is
+ * Copyright (C) 2016 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ *     This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN8I_V3S_H_
+#define _DT_BINDINGS_RST_SUN8I_V3S_H_
+
+#define RST_USB_PHY0		0
+
+#define RST_MBUS		1
+
+#define RST_BUS_CE		5
+#define RST_BUS_DMA		6
+#define RST_BUS_MMC0		7
+#define RST_BUS_MMC1		8
+#define RST_BUS_MMC2		9
+#define RST_BUS_DRAM		11
+#define RST_BUS_EMAC		12
+#define RST_BUS_HSTIMER		14
+#define RST_BUS_SPI0		15
+#define RST_BUS_OTG		17
+#define RST_BUS_EHCI0		18
+#define RST_BUS_OHCI0		22
+#define RST_BUS_VE		26
+#define RST_BUS_TCON0		27
+#define RST_BUS_CSI		30
+#define RST_BUS_DE		34
+#define RST_BUS_DBG		38
+#define RST_BUS_EPHY		39
+#define RST_BUS_CODEC		40
+#define RST_BUS_I2C0		46
+#define RST_BUS_I2C1		47
+#define RST_BUS_UART0		49
+#define RST_BUS_UART1		50
+#define RST_BUS_UART2		51
+
+#endif /* _DT_BINDINGS_RST_SUN8I_H3_H_ */
-- 
2.11.0

^ permalink raw reply related

* [PATCH 3/5] pinctrl: sunxi: add driver for V3s SoC
From: Icenowy Zheng @ 2017-01-03 15:16 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Stephen Boyd, Linus Walleij
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170103151629.19447-1-icenowy-ymACFijhrKM@public.gmane.org>

V3s SoC features only a pin controller (for the lack of CPUs part).

Add a driver for this controller.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 drivers/pinctrl/sunxi/Kconfig             |   4 +
 drivers/pinctrl/sunxi/Makefile            |   1 +
 drivers/pinctrl/sunxi/pinctrl-sun8i-v3s.c | 321 ++++++++++++++++++++++++++++++
 3 files changed, 326 insertions(+)
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-v3s.c

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index bff1ffc6f01e..3bd968cec28c 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -63,6 +63,10 @@ config PINCTRL_SUN8I_H3_R
 	def_bool MACH_SUN8I
 	select PINCTRL_SUNXI_COMMON
 
+config PINCTRL_SUN8I_V3S
+	def_bool MACH_SUN8I
+	select PINCTRL_SUNXI
+
 config PINCTRL_SUN9I_A80
 	def_bool MACH_SUN9I
 	select PINCTRL_SUNXI
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index 95f93d0561fc..9a955851f7f9 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -17,5 +17,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_A64)	+= pinctrl-sun50i-a64.o
 obj-$(CONFIG_PINCTRL_SUN8I_A83T)	+= pinctrl-sun8i-a83t.o
 obj-$(CONFIG_PINCTRL_SUN8I_H3)		+= pinctrl-sun8i-h3.o
 obj-$(CONFIG_PINCTRL_SUN8I_H3_R)	+= pinctrl-sun8i-h3-r.o
+obj-$(CONFIG_PINCTRL_SUN8I_V3S)		+= pinctrl-sun8i-v3s.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-v3s.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-v3s.c
new file mode 100644
index 000000000000..c86d3c42a905
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-v3s.c
@@ -0,0 +1,321 @@
+/*
+ * Allwinner V3s SoCs pinctrl driver.
+ *
+ * Copyright (C) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * Based on pinctrl-sun8i-h3.c, which is:
+ * Copyright (C) 2015 Jens Kuske <jenskuske-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * Based on pinctrl-sun8i-a23.c, which is:
+ * Copyright (C) 2014 Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
+ * Copyright (C) 2014 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_v3s_pins[] = {
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* TX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PB_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PB_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PB_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* D1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PB_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pwm0"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PB_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pwm1"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PB_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PB_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PB_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "uart0"),		/* TX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PB_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "uart0"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)),	/* PB_EINT9 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc2"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc2"),		/* CMD */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc2"),		/* RST */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* CS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc2"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MOSI */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* PCLK */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* MCLK */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* DE */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* HSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* VSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D8 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D9 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D10 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D11 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D15 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D12 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D18 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D13 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D19 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 18),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D14 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D20 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 19),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* D15 */
+		  SUNXI_FUNCTION(0x3, "lcd")),		/* D21 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 20),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* FIELD */
+		  SUNXI_FUNCTION(0x3, "csi_mipi")),	/* MCLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 21),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 22),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 23),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "lcd"),		/* D22 */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* RTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 24),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "lcd"),		/* D23 */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* CTS */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* MS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* DI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "uart0")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* DO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "uart0")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* CK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PG_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CMD */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PG_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PG_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PG_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PG_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PG_EINT5 */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_v3s_pinctrl_data = {
+	.pins = sun8i_v3s_pins,
+	.npins = ARRAY_SIZE(sun8i_v3s_pins),
+	.irq_banks = 2,
+	.irq_read_needs_mux = true
+};
+
+static int sun8i_v3s_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_init(pdev,
+				  &sun8i_v3s_pinctrl_data);
+}
+
+static const struct of_device_id sun8i_v3s_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun8i-v3s-pinctrl", },
+	{}
+};
+
+static struct platform_driver sun8i_v3s_pinctrl_driver = {
+	.probe	= sun8i_v3s_pinctrl_probe,
+	.driver	= {
+		.name		= "sun8i-v3s-pinctrl",
+		.of_match_table	= sun8i_v3s_pinctrl_match,
+	},
+};
+builtin_platform_driver(sun8i_v3s_pinctrl_driver);
-- 
2.11.0

^ permalink raw reply related

* [PATCH 4/5] ARM: dts: sunxi: add dtsi file for V3s SoC
From: Icenowy Zheng @ 2017-01-03 15:16 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Stephen Boyd, Linus Walleij
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170103151629.19447-1-icenowy-ymACFijhrKM@public.gmane.org>

As we have the pinctrl and clock support for the V3s SoC, it's now to
run a mainline Linux on it.

So add a .dtsi file for it.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 arch/arm/boot/dts/sun8i-v3s.dtsi | 257 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 257 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun8i-v3s.dtsi

diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
new file mode 100644
index 000000000000..084da7474afb
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ *     This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/clock/sun8i-v3s-ccu.h>
+#include <dt-bindings/reset/sun8i-v3s-ccu.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <0>;
+			clocks = <&ccu CLK_CPU>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		osc24M: osc24M_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+			clock-output-names = "osc24M";
+		};
+
+		osc32k: osc32k_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+			clock-output-names = "osc32k";
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		mmc0: mmc@01c0f000 {
+			compatible = "allwinner,sun7i-a20-mmc";
+			reg = <0x01c0f000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC0>,
+				 <&ccu CLK_MMC0>,
+				 <&ccu CLK_MMC0_OUTPUT>,
+				 <&ccu CLK_MMC0_SAMPLE>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
+			resets = <&ccu RST_BUS_MMC0>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc1: mmc@01c10000 {
+			compatible = "allwinner,sun7i-a20-mmc";
+			reg = <0x01c10000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC1>,
+				 <&ccu CLK_MMC1>,
+				 <&ccu CLK_MMC1_OUTPUT>,
+				 <&ccu CLK_MMC1_SAMPLE>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
+			resets = <&ccu RST_BUS_MMC1>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc2: mmc@01c11000 {
+			compatible = "allwinner,sun7i-a20-mmc";
+			reg = <0x01c11000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC2>,
+				 <&ccu CLK_MMC2>,
+				 <&ccu CLK_MMC2_OUTPUT>,
+				 <&ccu CLK_MMC2_SAMPLE>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
+			resets = <&ccu RST_BUS_MMC2>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		ccu: clock@01c20000 {
+			compatible = "allwinner,sun8i-v3s-ccu";
+			reg = <0x01c20000 0x400>;
+			clocks = <&osc24M>, <&osc32k>;
+			clock-names = "hosc", "losc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		rtc: rtc@01c20400 {
+			compatible = "allwinner,sun6i-a31-rtc";
+			reg = <0x01c20400 0x54>;
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pio: pinctrl@01c20800 {
+			compatible = "allwinner,sun8i-v3s-pinctrl";
+			reg = <0x01c20800 0x400>;
+			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+
+			uart0_pins_a: uart0@0 {
+				pins = "PB8", "PB9";
+				function = "uart0";
+				bias-pull-up;
+			};
+
+			mmc0_pins_a: mmc0@0 {
+				pins = "PF0", "PF1", "PF2", "PF3",
+				       "PF4", "PF5";
+				function = "mmc0";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+		};
+
+		timer@01c20c00 {
+			compatible = "allwinner,sun4i-a10-timer";
+			reg = <0x01c20c00 0xa0>;
+			interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc24M>;
+		};
+
+		wdt0: watchdog@01c20ca0 {
+			compatible = "allwinner,sun6i-a31-wdt";
+			reg = <0x01c20ca0 0x20>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		uart0: serial@01c28000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28000 0x400>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
+			status = "disabled";
+		};
+
+		uart1: serial@01c28400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28400 0x400>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART1>;
+			resets = <&ccu RST_BUS_UART1>;
+			status = "disabled";
+		};
+
+		uart2: serial@01c28800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28800 0x400>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART2>;
+			resets = <&ccu RST_BUS_UART2>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller@01c81000 {
+			compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+			reg = <0x01c81000 0x1000>,
+			      <0x01c82000 0x1000>,
+			      <0x01c84000 0x2000>,
+			      <0x01c86000 0x2000>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		};
+	};
+};
-- 
2.11.0

^ permalink raw reply related

* [PATCH 5/5] ARM: dts: sunxi: add support for Lichee Pi Zero board
From: Icenowy Zheng @ 2017-01-03 15:16 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Stephen Boyd, Linus Walleij
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170103151629.19447-1-icenowy-ymACFijhrKM@public.gmane.org>

Lichee Pi Zero is a small-sized V3s board, which is
breadboard-compatible, and with a MicroUSB port with both OTG function
and power function.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 arch/arm/boot/dts/Makefile                    |  3 +-
 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts | 73 +++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index cccdbcb557b6..3e099e9b1ad7 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -853,7 +853,8 @@ dtb-$(CONFIG_MACH_SUN8I) += \
 	sun8i-h3-orangepi-pc-plus.dtb \
 	sun8i-h3-orangepi-plus.dtb \
 	sun8i-h3-orangepi-plus2e.dtb \
-	sun8i-r16-parrot.dtb
+	sun8i-r16-parrot.dtb \
+	sun8i-v3s-licheepi-zero.dtb
 dtb-$(CONFIG_MACH_SUN9I) += \
 	sun9i-a80-optimus.dtb \
 	sun9i-a80-cubieboard4.dtb
diff --git a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
new file mode 100644
index 000000000000..0099affc6ce3
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ *     This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-v3s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+/ {
+	model = "Lichee Pi Zero";
+	compatible = "licheepi,licheepi-zero", "allwinner,sun8i-v3s";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&mmc0 {
+	pinctrl-0 = <&mmc0_pins_a>;
+	pinctrl-names = "default";
+	broken-cd;
+	bus-width = <4>;
+	vmmc-supply = <&reg_vcc3v3>;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-0 = <&uart0_pins_a>;
+	pinctrl-names = "default";
+	status = "okay";
+};
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH v7 3/4] arm64: dts: marvell: Add I2C definitions for the Armada 3700
From: Gregory CLEMENT @ 2017-01-03 15:20 UTC (permalink / raw)
  To: Romain Perier
  Cc: Mark Rutland, devicetree, Yahuda Yitschak, Omri Itach,
	Jason Cooper, Pawel Moll, Ian Campbell, Igal Liberman, Hanna Hawa,
	Wolfram Sang, Neta Zur Hershkovits, Nadav Haklai, Rob Herring,
	Andrew Lunn, linux-i2c, Kumar Gala, Shadi Ammouri, Marcin Wojtas,
	Thomas Petazzoni, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20161201110440.27530-4-romain.perier@free-electrons.com>

Hi Romain,
 
 On jeu., déc. 01 2016, Romain Perier <romain.perier@free-electrons.com> wrote:

> The Armada 3700 has two i2c bus interface units, this commit adds the
> definitions of the corresponding device nodes. It also enables the node
> on the development board for this SoC.
>
> Signed-off-by: Romain Perier <romain.perier@free-electrons.com>
> Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

Applied on mvebu/dt64

Thanks,

Gregory

> ---
>  arch/arm64/boot/dts/marvell/armada-3720-db.dts |  4 ++++
>  arch/arm64/boot/dts/marvell/armada-37xx.dtsi   | 18 ++++++++++++++++++
>  2 files changed, 22 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
> index 1372e9a6..16d84af 100644
> --- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
> +++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
> @@ -62,6 +62,10 @@
>  	};
>  };
>  
> +&i2c0 {
> +	status = "okay";
> +};
> +
>  /* CON3 */
>  &sata {
>  	status = "okay";
> diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> index e9bd587..1b0fd21 100644
> --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> @@ -98,6 +98,24 @@
>  			/* 32M internal register @ 0xd000_0000 */
>  			ranges = <0x0 0x0 0xd0000000 0x2000000>;
>  
> +			i2c0: i2c@11000 {
> +				compatible = "marvell,armada-3700-i2c";
> +				reg = <0x11000 0x24>;
> +				clocks = <&nb_periph_clk 10>;
> +				interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> +				mrvl,i2c-fast-mode;
> +				status = "disabled";
> +			};
> +
> +			i2c1: i2c@11080 {
> +				compatible = "marvell,armada-3700-i2c";
> +				reg = <0x11080 0x24>;
> +				clocks = <&nb_periph_clk 9>;
> +				interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
> +				mrvl,i2c-fast-mode;
> +				status = "disabled";
> +			};
> +
>  			uart0: serial@12000 {
>  				compatible = "marvell,armada-3700-uart";
>  				reg = <0x12000 0x400>;
> -- 
> 2.9.3
>

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE: [PATCH v2 6/7] dt-bindings: media: Add Renesas R-Car DRIF binding
From: Ramesh Shanmugasundaram @ 2017-01-03 15:20 UTC (permalink / raw)
  To: Geert Uytterhoeven, Laurent Pinchart
  Cc: Rob Herring, Mark Rutland, Mauro Carvalho Chehab, Hans Verkuil,
	Sakari Ailus, Antti Palosaari, Chris Paterson, Geert Uytterhoeven,
	Linux Media Mailing List, devicetree@vger.kernel.org,
	Linux-Renesas
In-Reply-To: <CAMuHMdXj-xBrnBXfYu6BeXr7Gfv4wogH4z610Ddq-BSyVS=-8Q@mail.gmail.com>

Hi Laurent, Geert,

Thanks for the review comments.

> > On Wednesday 21 Dec 2016 08:10:37 Ramesh Shanmugasundaram wrote:
> >> Add binding documentation for Renesas R-Car Digital Radio Interface
> >> (DRIF) controller.
> >>
> >> Signed-off-by: Ramesh Shanmugasundaram
> >> <ramesh.shanmugasundaram@bp.renesas.com> ---
> >>  .../devicetree/bindings/media/renesas,drif.txt     | 202
> ++++++++++++++++++
> >>  1 file changed, 202 insertions(+)
> >>  create mode 100644
> >> Documentation/devicetree/bindings/media/renesas,drif.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/media/renesas,drif.txt
> >> b/Documentation/devicetree/bindings/media/renesas,drif.txt new file
> >> mode
> >> 100644
> >> index 0000000..1f3feaf
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/media/renesas,drif.txt
> 
> >> +Optional properties of an internal channel when:
> >> +     - It is the only enabled channel of the bond (or)
> >> +     - If it acts as primary among enabled bonds
> >> +--------------------------------------------------------
> >> +- renesas,syncmd       : sync mode
> >> +                      0 (Frame start sync pulse mode. 1-bit width
> pulse
> >> +                         indicates start of a frame)
> >> +                      1 (L/R sync or I2S mode) (default)
> >> +- renesas,lsb-first    : empty property indicates lsb bit is received
> >> first.
> >> +                      When not defined msb bit is received first
> >> +(default)
> >> +- renesas,syncac-active: Indicates sync signal polarity, 0/1 for
> low/high
> >> +                      respectively. The default is 1 (active high)
> >> +- renesas,dtdl         : delay between sync signal and start of
> reception.
> >> +                      The possible values are represented in 0.5 clock
> >> +                      cycle units and the range is 0 to 4. The default
> >> +                      value is 2 (i.e.) 1 clock cycle delay.
> >> +- renesas,syncdl       : delay between end of reception and sync
> signal
> >> edge.
> >> +                      The possible values are represented in 0.5 clock
> >> +                      cycle units and the range is 0 to 4 & 6. The
> default
> >> +                      value is 0 (i.e.) no delay.
> >
> > Most of these properties are pretty similar to the video bus
> > properties defined at the endpoint level in
> > Documentation/devicetree/bindings/media/video-interfaces.txt. I
> > believe it would make sense to use OF graph and try to standardize
> > these properties similarly.
> 
> Note that the last two properties match the those in
> Documentation/devicetree/bindings/spi/sh-msiof.txt.
> We may want to use one DRIF channel as a plain SPI slave with the
> (modified) MSIOF driver in the future.

Should I leave it as it is or modify these as in video-interfaces.txt? Shall we conclude on this please?

Thanks,
Ramesh

^ permalink raw reply

* Re: [PATCH 1/3] dt: pwm: lpc32xx: add description of clocks and #pwm-cells properties
From: Sylvain Lemieux @ 2017-01-03 15:22 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Rob Herring, devicetree, Thierry Reding, linux-arm-kernel,
	linux-pwm
In-Reply-To: <5a865e27-e673-2f45-6c71-ca1e7d92a346@mleia.com>

Hi Rob,

On Wed, 2016-12-21 at 05:30 +0200, Vladimir Zapolskiy wrote:
> On 12/10/2016 01:51 AM, Vladimir Zapolskiy wrote:
> > Hi Rob,
> > 
> > On 12/09/2016 11:41 PM, Rob Herring wrote:
> >> On Mon, Dec 05, 2016 at 03:42:37AM +0200, Vladimir Zapolskiy wrote:
> >>> NXP LPC32xx SoCs have two simple independent PWM controllers with a single
> >>> output each, in this case there is no need to specify PWM channel argument
> >>> on client side, one cell for setting PWM output frequency is sufficient.
> >>>
> >>> Another added to the description property 'clocks' has a standard meaning
> >>> of a controller supply clock, in the LPC32xx User's Manual the clock is
> >>> denoted as PWM1_CLK or PWM2_CLK clock.
> >>>
> >>> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> >>> ---
> >>>  Documentation/devicetree/bindings/pwm/lpc32xx-pwm.txt | 7 +++++++
> >>>  1 file changed, 7 insertions(+)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/pwm/lpc32xx-pwm.txt b/Documentation/devicetree/bindings/pwm/lpc32xx-pwm.txt
> >>> index 74b5bc5..523d796 100644
> >>> --- a/Documentation/devicetree/bindings/pwm/lpc32xx-pwm.txt
> >>> +++ b/Documentation/devicetree/bindings/pwm/lpc32xx-pwm.txt
> >>> @@ -3,15 +3,22 @@ LPC32XX PWM controller
> >>>  Required properties:
> >>>  - compatible: should be "nxp,lpc3220-pwm"
> >>>  - reg: physical base address and length of the controller's registers
> >>> +- clocks: clock phandle and clock specifier pair
> >>> +- #pwm-cells: should be 1, the cell is used to specify the period in
> >>> +  nanoseconds.
> >>
> >> This use of the cell is a bit odd as the period is s/w config and this 
> >> would typically be a channel selection or such.
> > 
> > this is a classic PWM channel configuration property for PWM consumers
> > described in DT, for instance PWM frequency for display panel backlight
> > on boot.
> > 
> > I think >90% of PWM controllers with device tree bindings have this
> > argument in #pwm-cells, from bindings/pwm/pwm.txt :
> > 
> >     pwm-specifier typically encodes the chip-relative PWM number and
> >     the PWM period in nanoseconds.
> > 
> > You also may skim through phandle arguments of 'pwms' property,
> > commonly the second argument is the requested frequency.
> > 
> > In this particular case I just drop PWM channel number, because
> > the LPC32xx PWM controller has a single output channel.
> > 
> >> What if I want user specified/changed periods?
> >>
> > 
> > The preset period still can be changed over sysfs in runtime.
> 
> Rob, have I managed to answer your questions?
> 
> If you accept my clarification, could you please ack the change?
> 
> --
> With best wishes,
> Vladimir
> 
ping

Sylvain

^ permalink raw reply

* Re: [PATCH v1 2/3] dt-bindings: add binding for rk3328 power domains
From: Rob Herring @ 2017-01-03 15:24 UTC (permalink / raw)
  To: Elaine Zhang
  Cc: mark.rutland, devicetree, huangtao, heiko, tomeu.vizoso, xf,
	khilman, xxx, linux-kernel, linux-rockchip, cl, linux-arm-kernel,
	wxt
In-Reply-To: <1482464872-12954-3-git-send-email-zhangqing@rock-chips.com>

On Fri, Dec 23, 2016 at 11:47:51AM +0800, Elaine Zhang wrote:
> Add binding documentation for the power domains
> found on Rockchip RK3328 SoCs.
> But RK3328 SoC just support idle, not support pd.
> 
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
> ---
>  Documentation/devicetree/bindings/soc/rockchip/power_domain.txt | 3 +++
>  1 file changed, 3 insertions(+)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH 1/2] input: touchscreen: add driver for Zeitec ZET6223
From: Rob Herring @ 2017-01-03 15:24 UTC (permalink / raw)
  To: Jelle van der Waa
  Cc: Dmitry Torokhov, linux-input-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161223163214.7716-1-jelle-oJJ1AqDjjO4@public.gmane.org>

On Fri, Dec 23, 2016 at 05:32:13PM +0100, Jelle van der Waa wrote:
> This is a basic driver for the Zeitec ZET6223 I2C touchscreen
> controllers. The driver does not support firmware loading, which is not
> required for all tablets which contain this chip.
> 
> Signed-off-by: Jelle van der Waa <jelle-oJJ1AqDjjO4@public.gmane.org>
> ---
>  .../bindings/input/touchscreen/zet6223.txt         |  29 +++

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

>  drivers/input/touchscreen/Kconfig                  |  11 ++
>  drivers/input/touchscreen/Makefile                 |   1 +
>  drivers/input/touchscreen/zet6223.c                | 198 +++++++++++++++++++++
>  4 files changed, 239 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/zet6223.txt
>  create mode 100644 drivers/input/touchscreen/zet6223.c
--
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 2/2] devicetree: add vendor prefix for Zeitec
From: Rob Herring @ 2017-01-03 15:25 UTC (permalink / raw)
  To: Jelle van der Waa; +Cc: Dmitry Torokhov, linux-input, devicetree
In-Reply-To: <20161223163214.7716-2-jelle@vdwaa.nl>

On Fri, Dec 23, 2016 at 05:32:14PM +0100, Jelle van der Waa wrote:
> Signed-off-by: Jelle van der Waa <jelle@vdwaa.nl>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
>  1 file changed, 1 insertion(+)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH 0/4] Add support for the USB OTG function of Allwinner V3s
From: Icenowy Zheng @ 2017-01-03 15:25 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I, Bin Liu
  Cc: devicetree, linux-usb, linux-kernel, linux-arm-kernel,
	Icenowy Zheng

Allwinner V3s SoC come with a USB OTG controller, which is a bind of a Mentor
Graphics MUSB Dual-role controller and a private USB PHY.

Both the MUSB and the USB PHY slightly changed. (The MUSB is similar to the
one in the popular SBC SoC H3).

Add support for them.

The device tree patches depends on my preivous patchset, but the phy and musb
patches are independent (the device tree patches depend on them).

The MUSB patch may be picked for use on H3.

The clock of the USB part seems to need some hack in the U-Boot, they are at
my WIP u-boot repo:
https://github.com/Icenowy/u-boot-1/tree/v3s .

Icenowy Zheng (4):
  phy: sun4i-usb: add support for V3s USB PHY
  musb: sunxi: add support for the variant in H3/V3s SoC
  ARM: dts: sunxi: add usb_otg and usbphy node for V3s SoC
  ARM: dts: sun8i: add OTG function to Lichee Pi Zero

 .../devicetree/bindings/phy/sun4i-usb-phy.txt      |  1 +
 .../bindings/usb/allwinner,sun4i-a10-musb.txt      |  4 +--
 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts      | 10 +++++++
 arch/arm/boot/dts/sun8i-v3s.dtsi                   | 27 +++++++++++++++++
 drivers/phy/phy-sun4i-usb.c                        | 14 ++++++++-
 drivers/usb/musb/sunxi.c                           | 35 ++++++++++++++++++++--
 6 files changed, 86 insertions(+), 5 deletions(-)

-- 
2.11.0

^ permalink raw reply

* [PATCH 1/4] phy: sun4i-usb: add support for V3s USB PHY
From: Icenowy Zheng @ 2017-01-03 15:25 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I, Bin Liu
  Cc: devicetree, linux-usb, linux-kernel, linux-arm-kernel,
	Icenowy Zheng
In-Reply-To: <20170103152534.20118-1-icenowy@aosc.xyz>

Allwinner V3s come with a USB PHY controller slightly different to other
SoCs, with only one PHY.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt |  1 +
 drivers/phy/phy-sun4i-usb.c                             | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
index 287150db6db4..e42334258185 100644
--- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
@@ -10,6 +10,7 @@ Required properties:
   * allwinner,sun8i-a23-usb-phy
   * allwinner,sun8i-a33-usb-phy
   * allwinner,sun8i-h3-usb-phy
+  * allwinner,sun8i-v3s-usb-phy
   * allwinner,sun50i-a64-usb-phy
 - reg : a list of offset + length pairs
 - reg-names :
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index bf28a0fdd569..4102841a8ad2 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -99,6 +99,7 @@ enum sun4i_usb_phy_type {
 	sun6i_a31_phy,
 	sun8i_a33_phy,
 	sun8i_h3_phy,
+	sun8i_v3s_phy,
 	sun50i_a64_phy,
 };
 
@@ -188,7 +189,8 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 	spin_lock_irqsave(&phy_data->reg_lock, flags);
 
 	if (phy_data->cfg->type == sun8i_a33_phy ||
-	    phy_data->cfg->type == sun50i_a64_phy) {
+	    phy_data->cfg->type == sun50i_a64_phy ||
+	    phy_data->cfg->type == sun8i_v3s_phy) {
 		/* A33 or A64 needs us to set phyctl to 0 explicitly */
 		writel(0, phyctl);
 	}
@@ -825,6 +827,15 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
 	.enable_pmu_unk1 = true,
 };
 
+static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
+	.num_phys = 1,
+	.type = sun8i_v3s_phy,
+	.disc_thresh = 3,
+	.phyctl_offset = REG_PHYCTL_A33,
+	.dedicated_clocks = true,
+	.enable_pmu_unk1 = true,
+};
+
 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
 	.num_phys = 2,
 	.type = sun50i_a64_phy,
@@ -842,6 +853,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = {
 	{ .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg },
 	{ .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg },
 	{ .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg },
+	{ .compatible = "allwinner,sun8i-v3s-usb-phy", .data = &sun8i_v3s_cfg },
 	{ .compatible = "allwinner,sun50i-a64-usb-phy",
 	  .data = &sun50i_a64_cfg},
 	{ },
-- 
2.11.0

^ permalink raw reply related

* [PATCH 2/4] musb: sunxi: add support for the variant in H3/V3s SoC
From: Icenowy Zheng @ 2017-01-03 15:25 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I, Bin Liu
  Cc: devicetree, linux-usb, linux-kernel, linux-arm-kernel,
	Icenowy Zheng
In-Reply-To: <20170103152534.20118-1-icenowy@aosc.xyz>

Allwinner H3/V3s features a variant of MUSB controller, which lacks one
endpoint.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 .../bindings/usb/allwinner,sun4i-a10-musb.txt      |  4 +--
 drivers/usb/musb/sunxi.c                           | 35 ++++++++++++++++++++--
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
index 862cd7c79805..d9b42da016f3 100644
--- a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
+++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
@@ -2,8 +2,8 @@ Allwinner sun4i A10 musb DRC/OTG controller
 -------------------------------------------
 
 Required properties:
- - compatible      : "allwinner,sun4i-a10-musb", "allwinner,sun6i-a31-musb"
-                     or "allwinner,sun8i-a33-musb"
+ - compatible      : "allwinner,sun4i-a10-musb", "allwinner,sun6i-a31-musb",
+                     "allwinner,sun8i-a33-musb" or "allwinner,sun8i-h3-musb"
  - reg             : mmio address range of the musb controller
  - clocks          : clock specifier for the musb controller ahb gate clock
  - reset           : reset specifier for the ahb reset (A31 and newer only)
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index d0be0eadd0d9..48ecb1580817 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -645,6 +645,20 @@ static struct musb_fifo_cfg sunxi_musb_mode_cfg[] = {
 	MUSB_EP_FIFO_SINGLE(5, FIFO_RX, 512),
 };
 
+/* H3/V3s OTG supports only 4 endpoints */
+#define SUNXI_MUSB_MAX_EP_NUM_H3	5
+
+static struct musb_fifo_cfg sunxi_musb_mode_cfg_h3[] = {
+	MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512),
+};
+
 static struct musb_hdrc_config sunxi_musb_hdrc_config = {
 	.fifo_cfg       = sunxi_musb_mode_cfg,
 	.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg),
@@ -656,6 +670,18 @@ static struct musb_hdrc_config sunxi_musb_hdrc_config = {
 	.dma		= 0,
 };
 
+static struct musb_hdrc_config sunxi_musb_hdrc_config_h3 = {
+	.fifo_cfg       = sunxi_musb_mode_cfg_h3,
+	.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg_h3),
+	.multipoint	= true,
+	.dyn_fifo	= true,
+	.soft_con       = true,
+	.num_eps	= SUNXI_MUSB_MAX_EP_NUM_H3,
+	.ram_bits	= SUNXI_MUSB_RAM_BITS,
+	.dma		= 0,
+};
+
+
 static int sunxi_musb_probe(struct platform_device *pdev)
 {
 	struct musb_hdrc_platform_data	pdata;
@@ -698,7 +724,10 @@ static int sunxi_musb_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	pdata.platform_ops	= &sunxi_musb_ops;
-	pdata.config		= &sunxi_musb_hdrc_config;
+	if (!of_device_is_compatible(np, "allwinner,sun8i-h3-musb"))
+		pdata.config = &sunxi_musb_hdrc_config;
+	else
+		pdata.config = &sunxi_musb_hdrc_config_h3;
 
 	glue->dev = &pdev->dev;
 	INIT_WORK(&glue->work, sunxi_musb_work);
@@ -710,7 +739,8 @@ static int sunxi_musb_probe(struct platform_device *pdev)
 	if (of_device_is_compatible(np, "allwinner,sun6i-a31-musb"))
 		set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
 
-	if (of_device_is_compatible(np, "allwinner,sun8i-a33-musb")) {
+	if (of_device_is_compatible(np, "allwinner,sun8i-a33-musb") ||
+	    of_device_is_compatible(np, "allwinner,sun8i-h3-musb")) {
 		set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
 		set_bit(SUNXI_MUSB_FL_NO_CONFIGDATA, &glue->flags);
 	}
@@ -804,6 +834,7 @@ static const struct of_device_id sunxi_musb_match[] = {
 	{ .compatible = "allwinner,sun4i-a10-musb", },
 	{ .compatible = "allwinner,sun6i-a31-musb", },
 	{ .compatible = "allwinner,sun8i-a33-musb", },
+	{ .compatible = "allwinner,sun8i-h3-musb", },
 	{}
 };
 MODULE_DEVICE_TABLE(of, sunxi_musb_match);
-- 
2.11.0

^ permalink raw reply related

* [PATCH 3/4] ARM: dts: sunxi: add usb_otg and usbphy node for V3s SoC
From: Icenowy Zheng @ 2017-01-03 15:25 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I, Bin Liu
  Cc: devicetree, linux-usb, linux-kernel, linux-arm-kernel,
	Icenowy Zheng
In-Reply-To: <20170103152534.20118-1-icenowy@aosc.xyz>

V3s SoC features a USB PHY controller and a MUSB OTG controller.

Add device nodes for them.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 arch/arm/boot/dts/sun8i-v3s.dtsi | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index 084da7474afb..ebefc0fefef2 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -153,6 +153,33 @@
 			#size-cells = <0>;
 		};
 
+		usb_otg: usb@01c19000 {
+			compatible = "allwinner,sun8i-h3-musb";
+			reg = <0x01c19000 0x0400>;
+			clocks = <&ccu CLK_BUS_OTG>;
+			resets = <&ccu RST_BUS_OTG>;
+			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			extcon = <&usbphy 0>;
+			status = "disabled";
+		};
+
+		usbphy: phy@01c19400 {
+			compatible = "allwinner,sun8i-v3s-usb-phy";
+			reg = <0x01c19400 0x2c>,
+			      <0x01c1a800 0x4>;
+			reg-names = "phy_ctrl",
+				    "pmu0";
+			clocks = <&ccu CLK_USB_PHY0>;
+			clock-names = "usb0_phy";
+			resets = <&ccu RST_USB_PHY0>;
+			reset-names = "usb0_reset";
+			status = "disabled";
+			#phy-cells = <1>;
+		};
+
 		ccu: clock@01c20000 {
 			compatible = "allwinner,sun8i-v3s-ccu";
 			reg = <0x01c20000 0x400>;
-- 
2.11.0

^ permalink raw reply related

* [PATCH 4/4] ARM: dts: sun8i: add OTG function to Lichee Pi Zero
From: Icenowy Zheng @ 2017-01-03 15:25 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I, Bin Liu
  Cc: devicetree, linux-usb, linux-kernel, linux-arm-kernel,
	Icenowy Zheng
In-Reply-To: <20170103152534.20118-1-icenowy@aosc.xyz>

Lichee Pi Zero features a USB OTG port.

Add support for it.

Note: in order to use the Host mode, the board must be powered via the
+5V and GND pins.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
index 0099affc6ce3..3d9168cbaeca 100644
--- a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
+++ b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
@@ -71,3 +71,13 @@
 	pinctrl-names = "default";
 	status = "okay";
 };
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpio = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
-- 
2.11.0

^ permalink raw reply related

* Re: [RFC PATCH v2 1/4] devicetree: hwmon: Add bindings for ADC128D818
From: Rob Herring @ 2017-01-03 15:28 UTC (permalink / raw)
  To: Alexander Koch
  Cc: linux-kernel, linux-hwmon, devicetree, Mark Rutland, Jean Delvare,
	Guenter Roeck, Jiri Kosina
In-Reply-To: <20161223221205.8825-2-mail@alexanderkoch.net>

On Fri, Dec 23, 2016 at 11:12:02PM +0100, Alexander Koch wrote:
> Add bindings documentation for the ADC128D818 driver, featuring default I2C
> properties along with the optional 'mode' property for chip operation mode
> selection (see datasheet, sec. 8.4.1).
> 
> Signed-off-by: Alexander Koch <mail@alexanderkoch.net>
> ---
>  .../devicetree/bindings/hwmon/adc128d818.txt       | 39 ++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/hwmon/adc128d818.txt
> 
> diff --git a/Documentation/devicetree/bindings/hwmon/adc128d818.txt b/Documentation/devicetree/bindings/hwmon/adc128d818.txt
> new file mode 100644
> index 000000000000..5e14aa36a696
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwmon/adc128d818.txt
> @@ -0,0 +1,39 @@
> +TI ADC128D818 ADC System Monitor With Temperature Sensor
> +--------------------------------------------------------
> +
> +Operation modes:
> +
> + - Mode 0:  7 single-ended voltage readings (IN0-IN6),
> +            1 temperature reading (internal)
> + - Mode 1:  8 single-ended voltage readings (IN0-IN7),
> +            no temperature
> + - Mode 2:  4 pseudo-differential voltage readings
> +              (IN0-IN1, IN3-IN2, IN4-IN5, IN7-IN6),
> +            1 temperature reading (internal)
> + - Mode 3:  4 single-ended voltage readings (IN0-IN3),
> +            2 pseudo-differential voltage readings
> +              (IN4-IN5, IN7-IN6),
> +            1 temperature reading (internal)
> +
> +If no operation mode is configured via device tree, the driver defaults
> +to Mode 0.
> +
> +
> +Required node properties:
> +
> + - compatible:  must be set to "ti,adc128d818"
> + - reg:         I2C address of the device
> +
> +Optional node properties:
> +
> + - mode:        Operation mode (see above).

Needs a vendor prefix.

> +
> +
> +Example (operation mode 2):
> +
> +	adc128d818@1d {
> +		compatible = "ti,adc128d818";
> +		reg = <0x1d>;
> +		mode = /bits/ 8 <2>;

Need to specify above this is an 8-bit value. Or just drop the size 
here as there's little gain to use a byte here.

> +	};
> +
> -- 
> 2.11.0
> 

^ permalink raw reply

* Re: [PATCH 3/4] arm64: dts: exynos: make tm2 and tm2e independent from each other
From: Chanwoo Choi @ 2017-01-03 15:29 UTC (permalink / raw)
  To: Andi Shyti
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Kukjin Kim,
	Chanwoo Choi, Catalin Marinas, Jaechul Lee, Dmitry Torokhov,
	Will Deacon, linux-kernel, Andi Shyti, Javier Martinez Canillas,
	Rob Herring, Krzysztof Kozlowski, linux-input, galaxyra,
	beomho.seo, linux-arm-kernel
In-Reply-To: <20170103144056.4ft2ohmhgmezeney@jack.zhora.eu>

Hi Andi,

2017-01-03 23:40 GMT+09:00 Andi Shyti <andi@etezian.org>:
> Hi,
>
>> FWIW, I also agree with Chanwoo that the difference is too small to
>> need a common .dtsi file.
>
> in principle I don't like "switching on and off" properties by
> overwriting them with "status = disable", unless it's really
> necessary (and this case is not). Even for small differences. It
> makes the DTS harder to read and duplicates nodes with different
> values throughout the DTS include chain.
>
> In my opinion this approach should be discouraged.
>
> Besides, there are other overwritten differences in tm2e.dts that
> I think should be separated as well. The "common" file approach is
> widely used in arm/boot/dts/exynos* files.
>
> The "status = disable" looks to me more like a temporary hack
> rather than a permanent solution.
>
> In any case, still up to you :)
>
> Andi

I think that "status=disabled" of hsi2c_9 is not hack. The overwrite
is possible for Device-tree. But, there is just difference how to
support them with some method.

Except for touchkey, all peripheral device are same on both tm2 and
tm2e. There are only small difference for a few property value.

To understand the difference between tm2 and tm2e, I made the patch
(it is not complete version). If we implement the following patch, we
support both tm2 and tm2e. So, I think that it is not complex to
understand the h/w difference between tm2 and tm2e.

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
index 1db4e7f..09b6935 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
@@ -18,6 +18,17 @@
        compatible = "samsung,tm2e", "samsung,exynos5433";
 };

+&display_timings {
+       clock-frequency = <16523724>;
+       hactive = <1600>;
+};
+
+&hsi2c_9 {
+        /* TM2E don't use the separate touchkey device. Instead, touchscreen
+         * device support the touchkey device.*/
+       status = "disabled";
+};
+
 &ldo23_reg {
        regulator-name = "CAM_SEN_CORE_1.025V_AP";
        regulator-max-microvolt = <1050000>;
@@ -39,3 +50,7 @@
        regulator-min-microvolt = <3300000>;
        regulator-max-microvolt = <3300000>;
 };
+
+&touchscreen {
+       x-size = "1599";
+};

-- 
Best Regards,
Chanwoo Choi

^ permalink raw reply related

* Re: [PATCH] adc: add adc driver for Hisilicon BVT SOCs
From: Rob Herring @ 2017-01-03 15:30 UTC (permalink / raw)
  To: Allen Liu
  Cc: jic23, knaack.h, lars, pmeerw, mark.rutland, akinobu.mita,
	ludovic.desroches, krzk, vilhelm.gray, ksenija.stanojevic,
	zhiyong.tao, daniel.baluta, leonard.crestez, ray.jui,
	raveendra.padasalagi, mranostay, amsfield22, linux-iio,
	devicetree, linux-kernel, xuejiancheng, kevin.lixu
In-Reply-To: <1482544497-136656-1-git-send-email-liurenzhong@hisilicon.com>

On Sat, Dec 24, 2016 at 09:54:57AM +0800, Allen Liu wrote:
> Add ADC driver for the ADC controller found on HiSilicon BVT SOCs, like Hi3516CV300, etc.
> The ADC controller is primarily in charge of detecting voltage.
> 
> Reviewed-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
> Signed-off-by: Allen Liu <liurenzhong@hisilicon.com>
> ---
>  .../devicetree/bindings/iio/adc/hibvt-lsadc.txt    |  26 ++
>  drivers/iio/adc/Kconfig                            |  10 +
>  drivers/iio/adc/Makefile                           |   1 +
>  drivers/iio/adc/hibvt_lsadc.c                      | 344 +++++++++++++++++++++
>  4 files changed, 381 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt
>  create mode 100644 drivers/iio/adc/hibvt_lsadc.c
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt b/Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt
> new file mode 100644
> index 0000000..63de46e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/hibvt-lsadc.txt
> @@ -0,0 +1,26 @@
> +Hisilicon BVT Low Speed (LS) A/D Converter bindings
> +
> +Required properties:
> +- compatible: should be "hisilicon,<name>-lsadc"
> +   - "hisilicon,hibvt-lsadc": for hi3516cv300

Use the SoC name in the compatible string.

> +
> +- reg: physical base address of the controller and length of memory mapped
> +       region.
> +- interrupts: The interrupt number to the cpu. The interrupt specifier format
> +              depends on the interrupt controller.
> +- #io-channel-cells: Should be 1, see ../iio-bindings.txt
> +
> +Optional properties:
> +- resets: Must contain an entry for each entry in reset-names if need support
> +	  this option. See ../reset/reset.txt for details.
> +- reset-names: Must include the name "saradc-apb".
> +
> +Example:
> +	lsadc: hibvt-lsadc@120e0000 {

Just "adc@..."

> +			compatible = "hisilicon,hibvt-lsadc";
> +			reg = <0x120e0000 0x1000>;
> +			interrupts = <19>;
> +			resets = <&crg 0x7c 3>;
> +			reset-names = "lsadc-crg";
> +			status = "disabled";
> +	};

^ permalink raw reply

* Re: [PATCH 2/5] mfd: twl: remove useless header
From: Lee Jones @ 2017-01-03 15:30 UTC (permalink / raw)
  To: Nicolae Rosia
  Cc: Mark Rutland, devicetree, Baruch Siach, Tony Lindgren,
	Liam Girdwood, Rob Herring, linux-kernel, Paul Gortmaker,
	Mark Brown, Graeme Gregory, linux-omap, linux-arm-kernel
In-Reply-To: <20161126181326.14951-3-Nicolae_Rosia@mentor.com>

On Sat, 26 Nov 2016, Nicolae Rosia wrote:

> This header has one user, twl-core.c .
> Remove it before it gets more users.

The header is not useless.  It prevents us from having to place
external prototypes into C files.

> Signed-off-by: Nicolae Rosia <Nicolae_Rosia@mentor.com>
> ---
>  drivers/mfd/twl-core.c    |  8 ++++++--
>  drivers/mfd/twl-core.h    | 10 ----------
>  drivers/mfd/twl4030-irq.c |  2 --
>  drivers/mfd/twl6030-irq.c |  2 --
>  4 files changed, 6 insertions(+), 16 deletions(-)
>  delete mode 100644 drivers/mfd/twl-core.h
> 
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index 48b0668..e16084e 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -52,8 +52,6 @@
>  /* Register descriptions for audio */
>  #include <linux/mfd/twl4030-audio.h>
>  
> -#include "twl-core.h"
> -
>  /*
>   * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
>   * Management and System Companion Device" chips originally designed for
> @@ -150,6 +148,12 @@
>  
>  /*----------------------------------------------------------------------*/
>  
> +int twl6030_init_irq(struct device *dev, int irq_num);
> +int twl6030_exit_irq(void);
> +int twl4030_init_irq(struct device *dev, int irq_num);
> +int twl4030_exit_irq(void);
> +int twl4030_init_chip_irq(const char *chip);
> +
>  /* Structure for each TWL4030/TWL6030 Slave */
>  struct twl_client {
>  	struct i2c_client *client;
> diff --git a/drivers/mfd/twl-core.h b/drivers/mfd/twl-core.h
> deleted file mode 100644
> index 6ff99dc..0000000
> --- a/drivers/mfd/twl-core.h
> +++ /dev/null
> @@ -1,10 +0,0 @@
> -#ifndef __TWL_CORE_H__
> -#define __TWL_CORE_H__
> -
> -extern int twl6030_init_irq(struct device *dev, int irq_num);
> -extern int twl6030_exit_irq(void);
> -extern int twl4030_init_irq(struct device *dev, int irq_num);
> -extern int twl4030_exit_irq(void);
> -extern int twl4030_init_chip_irq(const char *chip);
> -
> -#endif /*  __TWL_CORE_H__ */
> diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
> index b46c0cf..000c231 100644
> --- a/drivers/mfd/twl4030-irq.c
> +++ b/drivers/mfd/twl4030-irq.c
> @@ -35,8 +35,6 @@
>  #include <linux/irqdomain.h>
>  #include <linux/i2c/twl.h>
>  
> -#include "twl-core.h"
> -
>  /*
>   * TWL4030 IRQ handling has two stages in hardware, and thus in software.
>   * The Primary Interrupt Handler (PIH) stage exposes status bits saying
> diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
> index 5357450..63eca76 100644
> --- a/drivers/mfd/twl6030-irq.c
> +++ b/drivers/mfd/twl6030-irq.c
> @@ -42,8 +42,6 @@
>  #include <linux/irqdomain.h>
>  #include <linux/of_device.h>
>  
> -#include "twl-core.h"
> -
>  /*
>   * TWL6030 (unlike its predecessors, which had two level interrupt handling)
>   * three interrupt registers INT_STS_A, INT_STS_B and INT_STS_C.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 2/2] can: spi: hi311x: Add Holt HI-311x CAN driver
From: Marc Kleine-Budde @ 2017-01-03 15:31 UTC (permalink / raw)
  To: Akshay Bhat, wg, robh+dt
  Cc: mark.rutland, linux-can, netdev, devicetree, linux-kernel,
	Akshay Bhat
In-Reply-To: <1479146144-29143-2-git-send-email-akshay.bhat@timesys.com>


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

On 11/14/2016 06:55 PM, Akshay Bhat wrote:
> This patch adds support for the Holt HI-311x CAN controller. The HI311x
> CAN controller is capable of transmitting and receiving standard data
> frames, extended data frames and remote frames. The HI311x interfaces
> with the host over SPI.

Don't use uint8_t and similar in the kernel, please use u8 instead.

> 
> Datasheet: www.holtic.com/documents/371-hi-3110_v-rev-jpdf.do
> 
> Signed-off-by: Akshay Bhat <nodeax@gmail.com>
> ---
>  drivers/net/can/spi/Kconfig  |    6 +
>  drivers/net/can/spi/Makefile |    1 +
>  drivers/net/can/spi/hi311x.c | 1071 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1078 insertions(+)
>  create mode 100644 drivers/net/can/spi/hi311x.c
> 
> diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig
> index 148cae5..9eb1bb1 100644
> --- a/drivers/net/can/spi/Kconfig
> +++ b/drivers/net/can/spi/Kconfig
> @@ -7,4 +7,10 @@ config CAN_MCP251X
>  	---help---
>  	  Driver for the Microchip MCP251x SPI CAN controllers.
>  
> +config CAN_HI311X
> +	tristate "Holt HI311x SPI CAN controllers"
> +	depends on CAN_DEV && SPI && HAS_DMA
> +	---help---
> +	  Driver for the Holt HI311x SPI CAN controllers.
> +
>  endmenu
> diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile
> index 0e86040..eac7c3a 100644
> --- a/drivers/net/can/spi/Makefile
> +++ b/drivers/net/can/spi/Makefile
> @@ -4,3 +4,4 @@
>  
>  
>  obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
> +obj-$(CONFIG_CAN_HI311X)	+= hi311x.o

Please keep sorted alphabetically. Same for the Kconfig.

> diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
> new file mode 100644
> index 0000000..1020166
> --- /dev/null
> +++ b/drivers/net/can/spi/hi311x.c
> @@ -0,0 +1,1071 @@
> +/* CAN bus driver for Holt HI3110 CAN Controller with SPI Interface
> + *
> + * Based on Microchip 251x CAN Controller (mcp251x) Linux kernel driver

You might want to add the copyright of the mcp authors.

> + *
> + * Copyright(C) Timesys Corporation 2016
> + *
> + * 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.
> + */
> +
> +#include <linux/can/core.h>
> +#include <linux/can/dev.h>
> +#include <linux/can/led.h>
> +#include <linux/clk.h>
> +#include <linux/completion.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/freezer.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/netdevice.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/spi/spi.h>
> +#include <linux/uaccess.h>
> +

Please use just a single space after each macro.

                              VVVVVVVV
> +#define HI3110_MASTER_RESET        0x56
> +#define HI3110_READ_CTRL0          0xD2
> +#define HI3110_READ_CTRL1          0xD4
> +#define HI3110_READ_STATF          0xE2
> +#define HI3110_WRITE_CTRL0         0x14
> +#define HI3110_WRITE_CTRL1         0x16
> +#define HI3110_WRITE_INTE          0x1C
> +#define HI3110_WRITE_BTR0          0x18
> +#define HI3110_WRITE_BTR1          0x1A
> +#define HI3110_READ_BTR0           0xD6
> +#define HI3110_READ_BTR1           0xD8
> +#define HI3110_READ_INTF           0xDE
> +#define HI3110_READ_ERR            0xDC
> +#define HI3110_READ_FIFO_WOTIME    0x48
> +#define HI3110_WRITE_FIFO          0x12
> +#define HI3110_READ_MESSTAT        0xDA
> +#define HI3110_READ_TEC            0xEC
> +
> +#define HI3110_CTRL0_MODE_MASK     (7 << 5)
> +#define HI3110_CTRL0_NORMAL_MODE   (0 << 5)
> +#define HI3110_CTRL0_LOOPBACK_MODE (1 << 5)
> +#define HI3110_CTRL0_MONITOR_MODE  (2 << 5)
> +#define HI3110_CTRL0_SLEEP_MODE    (3 << 5)
> +#define HI3110_CTRL0_INIT_MODE     (4 << 5)
> +
> +#define HI3110_CTRL1_TXEN          BIT(7)
> +
> +#define HI3110_INT_RXTMP           BIT(7)
> +#define HI3110_INT_RXFIFO          BIT(6)
> +#define HI3110_INT_TXCPLT          BIT(5)
> +#define HI3110_INT_BUSERR          BIT(4)
> +#define HI3110_INT_MCHG            BIT(3)
> +#define HI3110_INT_WAKEUP          BIT(2)
> +#define HI3110_INT_F1MESS          BIT(1)
> +#define HI3110_INT_F0MESS          BIT(0)
> +
> +#define HI3110_ERR_BUSOFF          BIT(7)
> +#define HI3110_ERR_TXERRP          BIT(6)
> +#define HI3110_ERR_RXERRP          BIT(5)
> +#define HI3110_ERR_BITERR          BIT(4)
> +#define HI3110_ERR_FRMERR          BIT(3)
> +#define HI3110_ERR_CRCERR          BIT(2)
> +#define HI3110_ERR_ACKERR          BIT(1)
> +#define HI3110_ERR_STUFERR         BIT(0)
> +#define HI3110_ERR_PROTOCOL_MASK   (0x1F)
> +
> +#define HI3110_STAT_RXFMTY         BIT(1)
> +
> +#define HI3110_BTR0_SJW_SHIFT      6
> +#define HI3110_BTR0_BRP_SHIFT      0
> +
> +#define HI3110_BTR1_SAMP_3PERBIT   (1 << 7)
> +#define HI3110_BTR1_SAMP_1PERBIT   (0 << 7)
> +#define HI3110_BTR1_TSEG2_SHIFT    4
> +#define HI3110_BTR1_TSEG1_SHIFT    0
> +
> +#define HI3110_FIFO_WOTIME_TAG_OFF 0
> +#define HI3110_FIFO_WOTIME_ID_OFF  1
> +#define HI3110_FIFO_WOTIME_DLC_OFF 5
> +#define HI3110_FIFO_WOTIME_DAT_OFF 6
> +
> +#define HI3110_FIFO_WOTIME_TAG_IDE BIT(7)
> +#define HI3110_FIFO_WOTIME_ID_RTR  BIT(0)
> +
> +#define HI3110_FIFO_TAG_OFF        0
> +#define HI3110_FIFO_ID_OFF         1
> +#define HI3110_FIFO_STD_DLC_OFF    3
> +#define HI3110_FIFO_STD_DATA_OFF   4
> +#define HI3110_FIFO_EXT_DLC_OFF    5
> +#define HI3110_FIFO_EXT_DATA_OFF   6
> +

Please add the already used HI3110_ namespace to these defines, too.

> +#define CAN_FRAME_MAX_DATA_LEN 8
> +#define RX_BUF_LEN             15
> +#define TX_STD_BUF_LEN         12
> +#define TX_EXT_BUF_LEN         14
> +#define CAN_FRAME_MAX_BITS     128
> +
> +#define TX_ECHO_SKB_MAX	1
> +
> +#define HI3110_OST_DELAY_MS (10)
> +
> +#define DEVICE_NAME "hi3110"
> +
> +static int hi3110_enable_dma = 1; /* Enable SPI DMA. Default: 1 (On) */
> +module_param(hi3110_enable_dma, int, 0444);
> +MODULE_PARM_DESC(hi3110_enable_dma, "Enable SPI DMA. Default: 1 (On)");
> +
> +static const struct can_bittiming_const hi3110_bittiming_const = {
> +	.name = DEVICE_NAME,
> +	.tseg1_min = 2,
> +	.tseg1_max = 16,
> +	.tseg2_min = 2,
> +	.tseg2_max = 8,
> +	.sjw_max = 4,
> +	.brp_min = 1,
> +	.brp_max = 64,
> +	.brp_inc = 1,
> +};
> +
> +enum hi3110_model {
> +	CAN_HI3110_HI3110	= 0x3110,
                         ^^^^^^^
single space here, too
> +};
> +
> +struct hi3110_priv {
> +	struct can_priv	   can;
                       ^^^^
here too
> +	struct net_device *net;
> +	struct spi_device *spi;
> +	enum hi3110_model model;
> +
> +	struct mutex hi3110_lock; /* SPI device lock */
> +
> +	u8 *spi_tx_buf;
> +	u8 *spi_rx_buf;
> +	dma_addr_t spi_tx_dma;
> +	dma_addr_t spi_rx_dma;
> +
> +	struct sk_buff *tx_skb;
> +	int tx_len;
> +
> +	struct workqueue_struct *wq;
> +	struct work_struct tx_work;
> +	struct work_struct restart_work;
> +
> +	int force_quit;
> +	int after_suspend;

Please add the already used HI3110_ namespace to these defines, too.

> +#define AFTER_SUSPEND_UP 1
> +#define AFTER_SUSPEND_DOWN 2
> +#define AFTER_SUSPEND_POWER 4
> +#define AFTER_SUSPEND_RESTART 8

> +	int restart_tx;
> +	struct regulator *power;
> +	struct regulator *transceiver;
> +	struct clk *clk;
> +};
> +
> +static void hi3110_clean(struct net_device *net)
> +{
> +	struct hi3110_priv *priv = netdev_priv(net);
> +
> +	if (priv->tx_skb || priv->tx_len)
> +		net->stats.tx_errors++;
> +	if (priv->tx_skb)
> +		dev_kfree_skb(priv->tx_skb);
> +	if (priv->tx_len)
> +		can_free_echo_skb(priv->net, 0);
> +	priv->tx_skb = NULL;
> +	priv->tx_len = 0;
> +}
> +
> +/* Note about handling of error return of hi3110_spi_trans: accessing
> + * registers via SPI is not really different conceptually than using
> + * normal I/O assembler instructions, although it's much more
> + * complicated from a practical POV. So it's not advisable to always
> + * check the return value of this function. Imagine that every
> + * read{b,l}, write{b,l} and friends would be bracketed in "if ( < 0)
> + * error();", it would be a great mess (well there are some situation
> + * when exception handling C++ like could be useful after all). So we
> + * just check that transfers are OK at the beginning of our
> + * conversation with the chip and to avoid doing really nasty things
> + * (like injecting bogus packets in the network stack).
> + */
> +static int hi3110_spi_trans(struct spi_device *spi, int len)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +	struct spi_transfer t = {
> +		.tx_buf = priv->spi_tx_buf,
> +		.rx_buf = priv->spi_rx_buf,
> +		.len = len,
> +		.cs_change = 0,
> +	};
> +	struct spi_message m;
> +	int ret;
> +
> +	spi_message_init(&m);
> +
> +	if (hi3110_enable_dma) {
> +		t.tx_dma = priv->spi_tx_dma;
> +		t.rx_dma = priv->spi_rx_dma;
> +		m.is_dma_mapped = 1;
> +	}
> +
> +	spi_message_add_tail(&t, &m);
> +
> +	ret = spi_sync(spi, &m);
> +
> +	if (ret)
> +		dev_err(&spi->dev, "spi transfer failed: ret = %d\n", ret);
> +	return ret;
> +}
> +
> +static u8 hi3110_cmd(struct spi_device *spi, uint8_t command)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +
> +	priv->spi_tx_buf[0] = command;
> +	dev_dbg(&spi->dev, "hi3110_cmd: %02X\n", command);
> +
> +	return hi3110_spi_trans(spi, 1);
> +}
> +
> +static u8 hi3110_read(struct spi_device *spi, uint8_t command)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +	u8 val = 0;
> +
> +	priv->spi_tx_buf[0] = command;
> +	hi3110_spi_trans(spi, 2);
> +	val = priv->spi_rx_buf[1];
> +	dev_dbg(&spi->dev, "hi3110_read: %02X, %02X\n", command, val);
> +
> +	return val;
> +}
> +
> +static void hi3110_write(struct spi_device *spi, u8 reg, uint8_t val)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +
> +	priv->spi_tx_buf[0] = reg;
> +	priv->spi_tx_buf[1] = val;
> +	dev_dbg(&spi->dev, "hi3110_write: %02X, %02X\n", reg, val);
> +
> +	hi3110_spi_trans(spi, 2);
> +}
> +
> +static void hi3110_hw_tx_frame(struct spi_device *spi, u8 *buf, int len)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +
> +	priv->spi_tx_buf[0] = HI3110_WRITE_FIFO;
> +	memcpy(priv->spi_tx_buf + 1, buf, len);
> +	hi3110_spi_trans(spi, len + 1);
> +}
> +
> +static void hi3110_hw_tx(struct spi_device *spi, struct can_frame *frame)
> +{
> +	u8 buf[TX_EXT_BUF_LEN];
> +
> +	buf[HI3110_FIFO_TAG_OFF] = 0;
> +
> +	if (frame->can_id & CAN_EFF_FLAG) {
> +		/* Extended frame */
> +		buf[HI3110_FIFO_ID_OFF] = (frame->can_id & CAN_EFF_MASK) >> 21;
> +		buf[HI3110_FIFO_ID_OFF + 1] =
> +			((((frame->can_id & CAN_EFF_MASK) >> 18) & 0x07) << 5) |

Why do you first shift down then up?

> +			0x18 | /* Recessive SRR and IDE */

Can you add a define for the 0x18?

> +			(((frame->can_id & CAN_EFF_MASK) >> 15) & 0x07);
> +		buf[HI3110_FIFO_ID_OFF + 2] =
> +			(frame->can_id & CAN_EFF_MASK) >> 7;
> +		buf[HI3110_FIFO_ID_OFF + 3] =
> +			((frame->can_id & CAN_EFF_MASK) << 1) |
> +			((frame->can_id & CAN_RTR_FLAG) ? 1 : 0);
> +
> +		buf[HI3110_FIFO_EXT_DLC_OFF] = frame->can_dlc;
> +
> +		memcpy(buf + HI3110_FIFO_EXT_DATA_OFF,
> +		       frame->data, frame->can_dlc);
> +
> +		hi3110_hw_tx_frame(spi, buf, TX_EXT_BUF_LEN -
> +				   (CAN_FRAME_MAX_DATA_LEN - frame->can_dlc));
> +	} else {
> +		/* Standard frame */
> +		buf[HI3110_FIFO_ID_OFF] =   (frame->can_id & CAN_SFF_MASK) >> 3;
> +		buf[HI3110_FIFO_ID_OFF + 1] =
> +			((frame->can_id & CAN_SFF_MASK) << 5) |
> +			((frame->can_id & CAN_RTR_FLAG) ? (1 << 4) : 0);
> +
> +		buf[HI3110_FIFO_STD_DLC_OFF] = frame->can_dlc;
> +
> +		memcpy(buf + HI3110_FIFO_STD_DATA_OFF,
> +		       frame->data, frame->can_dlc);
> +
> +		hi3110_hw_tx_frame(spi, buf, TX_STD_BUF_LEN -
> +				   (CAN_FRAME_MAX_DATA_LEN - frame->can_dlc));
> +	}
> +}
> +
> +static void hi3110_hw_rx_frame(struct spi_device *spi, u8 *buf)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +
> +	priv->spi_tx_buf[0] = HI3110_READ_FIFO_WOTIME;
> +	hi3110_spi_trans(spi, RX_BUF_LEN);
> +	memcpy(buf, priv->spi_rx_buf + 1, RX_BUF_LEN - 1);
> +}
> +
> +static void hi3110_hw_rx(struct spi_device *spi)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +	struct sk_buff *skb;
> +	struct can_frame *frame;
> +	u8 buf[RX_BUF_LEN - 1];
> +
> +	skb = alloc_can_skb(priv->net, &frame);
> +	if (!skb) {
> +		dev_err(&spi->dev, "cannot allocate RX skb\n");
> +		priv->net->stats.rx_dropped++;
> +		return;
> +	}
> +
> +	hi3110_hw_rx_frame(spi, buf);
> +	if (buf[HI3110_FIFO_WOTIME_TAG_OFF] & HI3110_FIFO_WOTIME_TAG_IDE) {
> +		/* IDE is recessive (1), indicating extended 29-bit frame */
> +		frame->can_id = CAN_EFF_FLAG;
> +		frame->can_id |=
> +		 (buf[HI3110_FIFO_WOTIME_ID_OFF] << 21) |
> +		 (((buf[HI3110_FIFO_WOTIME_ID_OFF + 1] & 0xE0) >> 5) << 18) |
> +		 ((buf[HI3110_FIFO_WOTIME_ID_OFF + 1] & 0x07) << 15) |
> +		 (buf[HI3110_FIFO_WOTIME_ID_OFF + 2] << 7) |
> +		 (buf[HI3110_FIFO_WOTIME_ID_OFF + 3] >> 1);
> +	} else {
> +		/* IDE is dominant (0), frame indicating standard 11-bit */
> +		frame->can_id =
> +			(buf[HI3110_FIFO_WOTIME_ID_OFF] << 3) |
> +			((buf[HI3110_FIFO_WOTIME_ID_OFF + 1] & 0xE0) >> 5);
> +	}
> +
> +	if (buf[HI3110_FIFO_WOTIME_ID_OFF + 3] & HI3110_FIFO_WOTIME_ID_RTR) {
> +		/* RTR is recessive (1), indicating remote request frame */
> +		frame->can_id |= CAN_RTR_FLAG;
> +	}
> +
> +	/* Data length */
> +	frame->can_dlc = get_can_dlc(buf[HI3110_FIFO_WOTIME_DLC_OFF] & 0x0F);
> +	memcpy(frame->data, buf + HI3110_FIFO_WOTIME_DAT_OFF, frame->can_dlc);
> +
> +	priv->net->stats.rx_packets++;
> +	priv->net->stats.rx_bytes += frame->can_dlc;
> +
> +	can_led_event(priv->net, CAN_LED_EVENT_RX);
> +
> +	netif_rx_ni(skb);
> +}
> +
> +static void hi3110_hw_sleep(struct spi_device *spi)
> +{
> +	hi3110_write(spi, HI3110_WRITE_CTRL0, HI3110_CTRL0_SLEEP_MODE);
> +}
> +
> +static netdev_tx_t hi3110_hard_start_xmit(struct sk_buff *skb,
> +					  struct net_device *net)
> +{
> +	struct hi3110_priv *priv = netdev_priv(net);
> +	struct spi_device *spi = priv->spi;
> +
> +	if (priv->tx_skb || priv->tx_len) {
> +		dev_warn(&spi->dev, "hard_xmit called while tx busy\n");
> +		return NETDEV_TX_BUSY;
> +	}
> +
> +	if (can_dropped_invalid_skb(net, skb))
> +		return NETDEV_TX_OK;
> +
> +	netif_stop_queue(net);
> +	priv->tx_skb = skb;
> +	queue_work(priv->wq, &priv->tx_work);
> +
> +	return NETDEV_TX_OK;
> +}
> +
> +static int hi3110_do_set_mode(struct net_device *net, enum can_mode mode)
> +{
> +	struct hi3110_priv *priv = netdev_priv(net);
> +
> +	switch (mode) {
> +	case CAN_MODE_START:
> +		hi3110_clean(net);
> +		/* We have to delay work since SPI I/O may sleep */
> +		priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +		priv->restart_tx = 1;
> +		if (priv->can.restart_ms == 0)
> +			priv->after_suspend = AFTER_SUSPEND_RESTART;
> +		queue_work(priv->wq, &priv->restart_work);
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	return 0;
> +}
> +
> +static int hi3110_set_normal_mode(struct spi_device *spi)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +	u8 reg;
> +
> +	hi3110_write(spi, HI3110_WRITE_INTE, HI3110_INT_BUSERR |
> +		     HI3110_INT_RXFIFO | HI3110_INT_TXCPLT);
> +
> +	/* Enable TX */
> +	hi3110_write(spi, HI3110_WRITE_CTRL1, HI3110_CTRL1_TXEN);
> +
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
> +		/* Put device into loopback mode */
> +		hi3110_write(spi, HI3110_WRITE_CTRL0,
> +			     HI3110_CTRL0_LOOPBACK_MODE);
> +	} else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
> +		/* Put device into listen-only mode */
> +		hi3110_write(spi, HI3110_WRITE_CTRL0,
> +			     HI3110_CTRL0_MONITOR_MODE);
> +	} else {
> +		/* Put device into normal mode */
> +		hi3110_write(spi, HI3110_WRITE_CTRL0,
> +			     HI3110_CTRL0_NORMAL_MODE);
> +
> +		/* Wait for the device to enter normal mode */
> +		mdelay(HI3110_OST_DELAY_MS);
> +		reg = hi3110_read(spi, HI3110_READ_CTRL0);
> +		if ((reg & HI3110_CTRL0_MODE_MASK) != HI3110_CTRL0_NORMAL_MODE)
> +			return -EBUSY;
> +	}
> +	priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +	return 0;
> +}
> +
> +static int hi3110_do_set_bittiming(struct net_device *net)
> +{
> +	struct hi3110_priv *priv = netdev_priv(net);
> +	struct can_bittiming *bt = &priv->can.bittiming;
> +	struct spi_device *spi = priv->spi;
> +
> +	hi3110_write(spi, HI3110_WRITE_BTR0,
> +		     ((bt->sjw - 1) << HI3110_BTR0_SJW_SHIFT) |
> +		     ((bt->brp - 1) << HI3110_BTR0_BRP_SHIFT));
> +
> +	hi3110_write(spi, HI3110_WRITE_BTR1,
> +		     (priv->can.ctrlmode &
> +		     CAN_CTRLMODE_3_SAMPLES ?
> +		     HI3110_BTR1_SAMP_3PERBIT : HI3110_BTR1_SAMP_1PERBIT) |
> +		     ((bt->phase_seg1 + bt->prop_seg - 1)
> +		     << HI3110_BTR1_TSEG1_SHIFT) |
> +		     ((bt->phase_seg2 - 1) << HI3110_BTR1_TSEG2_SHIFT));
> +
> +	dev_dbg(&spi->dev, "BT: 0x%02x 0x%02x\n",
> +		hi3110_read(spi, HI3110_READ_BTR0),
> +		hi3110_read(spi, HI3110_READ_BTR1));
> +
> +	return 0;
> +}
> +
> +static int hi3110_setup(struct net_device *net, struct hi3110_priv *priv,
> +			struct spi_device *spi)

onlt the first parameter is used.

> +{
> +	hi3110_do_set_bittiming(net);
> +	return 0;
> +}
> +
> +static int hi3110_hw_reset(struct spi_device *spi)
> +{
> +	u8 reg;
> +	int ret;
> +
> +	/* Wait for oscillator startup timer after power up */
> +	mdelay(HI3110_OST_DELAY_MS);
> +
> +	ret = hi3110_cmd(spi, HI3110_MASTER_RESET);
> +	if (ret)
> +		return ret;
> +
> +	/* Wait for oscillator startup timer after reset */
> +	mdelay(HI3110_OST_DELAY_MS);
> +
> +	reg = hi3110_read(spi, HI3110_READ_CTRL0);
> +	if ((reg & HI3110_CTRL0_MODE_MASK) != HI3110_CTRL0_INIT_MODE)
> +		return -ENODEV;
> +
> +	/* As per the datasheet it appears the error flags are
> +	 * not cleared on reset. Explicitly clear them by performing a read
> +	 */
> +	hi3110_read(spi, HI3110_READ_ERR);
> +
> +	return 0;
> +}
> +
> +static int hi3110_hw_probe(struct spi_device *spi)
> +{
> +	u8 statf;
> +
> +	hi3110_hw_reset(spi);
> +
> +	/* Confirm correct operation by checking against reset values
> +	 * in datasheet
> +	 */
> +	statf = hi3110_read(spi, HI3110_READ_STATF);
> +
> +	dev_dbg(&spi->dev, "statf: %02X\n", statf);
> +
> +	if (statf != 0x82)
> +		return -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int hi3110_power_enable(struct regulator *reg, int enable)
> +{
> +	if (IS_ERR_OR_NULL(reg))
> +		return 0;
> +
> +	if (enable)
> +		return regulator_enable(reg);
> +	else
> +		return regulator_disable(reg);
> +}
> +
> +static void hi3110_open_clean(struct net_device *net)
> +{
> +	struct hi3110_priv *priv = netdev_priv(net);
> +	struct spi_device *spi = priv->spi;
> +
> +	free_irq(spi->irq, priv);
> +	hi3110_hw_sleep(spi);
> +	hi3110_power_enable(priv->transceiver, 0);
> +	close_candev(net);
> +}
> +
> +static int hi3110_stop(struct net_device *net)
> +{
> +	struct hi3110_priv *priv = netdev_priv(net);
> +	struct spi_device *spi = priv->spi;
> +
> +	close_candev(net);
> +
> +	priv->force_quit = 1;
> +	free_irq(spi->irq, priv);
> +	destroy_workqueue(priv->wq);
> +	priv->wq = NULL;
> +
> +	mutex_lock(&priv->hi3110_lock);
> +
> +	/* Disable transmit, interrupts and clear flags */
> +	hi3110_write(spi, HI3110_WRITE_CTRL1, 0x0);
> +	hi3110_write(spi, HI3110_WRITE_INTE, 0x0);
> +	hi3110_read(spi, HI3110_READ_INTF);
> +
> +	hi3110_clean(net);
> +
> +	hi3110_hw_sleep(spi);
> +
> +	hi3110_power_enable(priv->transceiver, 0);
> +
> +	priv->can.state = CAN_STATE_STOPPED;
> +
> +	mutex_unlock(&priv->hi3110_lock);
> +
> +	can_led_event(net, CAN_LED_EVENT_STOP);
> +
> +	return 0;
> +}
> +
> +static void hi3110_error_skb(struct net_device *net, int can_id,
> +			     int data1, int data2)
> +{
> +	struct sk_buff *skb;
> +	struct can_frame *frame;
> +
> +	skb = alloc_can_err_skb(net, &frame);
> +	if (skb) {
> +		frame->can_id |= can_id;
> +		frame->data[1] = data1;
> +		frame->data[2] = data2;
> +		netif_rx_ni(skb);
> +	} else {
> +		netdev_err(net, "cannot allocate error skb\n");
> +	}
> +}
> +
> +static void hi3110_tx_work_handler(struct work_struct *ws)
> +{
> +	struct hi3110_priv *priv = container_of(ws, struct hi3110_priv,
> +						 tx_work);
> +	struct spi_device *spi = priv->spi;
> +	struct net_device *net = priv->net;
> +	struct can_frame *frame;
> +
> +	mutex_lock(&priv->hi3110_lock);
> +	if (priv->tx_skb) {
> +		if (priv->can.state == CAN_STATE_BUS_OFF) {
> +			hi3110_clean(net);
> +		} else {
> +			frame = (struct can_frame *)priv->tx_skb->data;
> +
> +			if (frame->can_dlc > CAN_FRAME_MAX_DATA_LEN)
> +				frame->can_dlc = CAN_FRAME_MAX_DATA_LEN;

this has already been checked

> +			hi3110_hw_tx(spi, frame);
> +			priv->tx_len = 1 + frame->can_dlc;
> +			can_put_echo_skb(priv->tx_skb, net, 0);
> +			priv->tx_skb = NULL;
> +		}
> +	}
> +	mutex_unlock(&priv->hi3110_lock);
> +}
> +
> +static void hi3110_restart_work_handler(struct work_struct *ws)
> +{
> +	struct hi3110_priv *priv = container_of(ws, struct hi3110_priv,
> +						 restart_work);
> +	struct spi_device *spi = priv->spi;
> +	struct net_device *net = priv->net;
> +
> +	mutex_lock(&priv->hi3110_lock);
> +	if (priv->after_suspend) {
> +		hi3110_hw_reset(spi);
> +		hi3110_setup(net, priv, spi);
> +		if (priv->after_suspend & AFTER_SUSPEND_RESTART) {
> +			hi3110_set_normal_mode(spi);
> +		} else if (priv->after_suspend & AFTER_SUSPEND_UP) {
> +			netif_device_attach(net);
> +			hi3110_clean(net);
> +			hi3110_set_normal_mode(spi);
> +			netif_wake_queue(net);
> +		} else {
> +			hi3110_hw_sleep(spi);
> +		}
> +		priv->after_suspend = 0;
> +		priv->force_quit = 0;
> +	}
> +
> +	if (priv->restart_tx) {
> +		priv->restart_tx = 0;
> +		hi3110_clean(net);
> +		netif_wake_queue(net);
> +		hi3110_error_skb(net, CAN_ERR_RESTARTED, 0, 0);
> +	}
> +	mutex_unlock(&priv->hi3110_lock);
> +}
> +
> +static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
> +{
> +	struct hi3110_priv *priv = dev_id;
> +	struct spi_device *spi = priv->spi;
> +	struct net_device *net = priv->net;
> +
> +	mutex_lock(&priv->hi3110_lock);
> +
> +	while (!priv->force_quit) {
> +		enum can_state new_state;
> +		u8 intf;
> +		u8 eflag;
> +		int can_id = 0, data1 = 0, data2 = 0;
> +
> +		while (!(HI3110_STAT_RXFMTY &
> +			hi3110_read(spi, HI3110_READ_STATF))) {
> +			hi3110_hw_rx(spi);
> +		};
> +
> +		intf = hi3110_read(spi, HI3110_READ_INTF);
> +		eflag = hi3110_read(spi, HI3110_READ_ERR);

does the hardware supports multiple reads with a single transfer? If so
make use of it, for performance reasons.

> +		/* Update can state */
> +		if (eflag & HI3110_ERR_BUSOFF) {
> +			new_state = CAN_STATE_BUS_OFF;
> +			can_id |= CAN_ERR_BUSOFF;
> +		} else if (eflag & HI3110_ERR_TXERRP) {
> +			new_state = CAN_STATE_ERROR_PASSIVE;
> +			can_id |= CAN_ERR_CRTL;
> +			data1 |= CAN_ERR_CRTL_TX_PASSIVE;
> +		} else if (eflag & HI3110_ERR_RXERRP) {
> +			new_state = CAN_STATE_ERROR_PASSIVE;
> +			can_id |= CAN_ERR_CRTL;
> +			data1 |= CAN_ERR_CRTL_RX_PASSIVE;
> +		} else {
> +			new_state = CAN_STATE_ERROR_ACTIVE;
> +		}
> +
> +		/* Check for protocol errors */
> +		if (eflag & HI3110_ERR_PROTOCOL_MASK) {
> +			can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> +			priv->can.can_stats.bus_error++;
> +			priv->net->stats.rx_errors++;
> +			if (eflag & HI3110_ERR_BITERR)
> +				data2 |= CAN_ERR_PROT_BIT;
> +			else if (eflag & HI3110_ERR_FRMERR)
> +				data2 |= CAN_ERR_PROT_FORM;
> +			else if (eflag & HI3110_ERR_STUFERR)
> +				data2 |= CAN_ERR_PROT_STUFF;
> +			else
> +				data2 |= CAN_ERR_PROT_UNSPEC;
> +		}
> +
> +		/* Update can state statistics */
> +		switch (priv->can.state) {
> +		case CAN_STATE_ERROR_ACTIVE:
> +			if (new_state >= CAN_STATE_ERROR_WARNING &&
> +			    new_state <= CAN_STATE_BUS_OFF)
> +				priv->can.can_stats.error_warning++;
> +		/* fallthrough */
> +		case CAN_STATE_ERROR_WARNING:
> +			if (new_state >= CAN_STATE_ERROR_PASSIVE &&
> +			    new_state <= CAN_STATE_BUS_OFF)
> +				priv->can.can_stats.error_passive++;
> +			break;
> +		default:
> +			break;
> +		}
> +		priv->can.state = new_state;
> +
> +		if (intf & HI3110_INT_BUSERR) {
> +			/* Note: HI3110 Does report overflow errors */
> +			hi3110_error_skb(net, can_id, data1, data2);
> +		}
> +
> +		if (priv->can.state == CAN_STATE_BUS_OFF) {
> +			if (priv->can.restart_ms == 0) {
> +				priv->force_quit = 1;
> +				priv->can.can_stats.bus_off++;
> +				can_bus_off(net);
> +				hi3110_hw_sleep(spi);
> +				break;
> +			}
> +		}
> +
> +		if (intf == 0)
> +			break;
> +
> +		if (intf & HI3110_INT_TXCPLT) {
> +			net->stats.tx_packets++;
> +			net->stats.tx_bytes += priv->tx_len - 1;
> +			can_led_event(net, CAN_LED_EVENT_TX);
> +			if (priv->tx_len) {
> +				can_get_echo_skb(net, 0);
> +				priv->tx_len = 0;
> +			}
> +			netif_wake_queue(net);
> +		}
> +	}
> +	mutex_unlock(&priv->hi3110_lock);
> +	return IRQ_HANDLED;
> +}
> +
> +static int hi3110_open(struct net_device *net)
> +{
> +	struct hi3110_priv *priv = netdev_priv(net);
> +	struct spi_device *spi = priv->spi;
> +	unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_RISING;
> +	int ret;
> +
> +	ret = open_candev(net);
> +	if (ret) {
> +		dev_err(&spi->dev, "unable to set initial baudrate!\n");
> +		return ret;
> +	}
> +
> +	mutex_lock(&priv->hi3110_lock);
> +	hi3110_power_enable(priv->transceiver, 1);
> +
> +	priv->force_quit = 0;
> +	priv->tx_skb = NULL;
> +	priv->tx_len = 0;
> +
> +	ret = request_threaded_irq(spi->irq, NULL, hi3110_can_ist,
> +				   flags, DEVICE_NAME, priv);
> +	if (ret) {
> +		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);

add propoer goto targets at the and of this function, for easier error
handling cleanup. This mean basically get rid of hi3110_open_clean(net).

> +		hi3110_power_enable(priv->transceiver, 0);
> +		close_candev(net);
> +		goto open_unlock;
> +	}
> +
> +	priv->wq = alloc_workqueue("hi3110_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
> +			   0);
> +	INIT_WORK(&priv->tx_work, hi3110_tx_work_handler);
> +	INIT_WORK(&priv->restart_work, hi3110_restart_work_handler);
> +
> +	ret = hi3110_hw_reset(spi);
> +	if (ret) {
> +		hi3110_open_clean(net);
> +		goto open_unlock;
> +	}
> +	ret = hi3110_setup(net, priv, spi);
> +	if (ret) {
> +		hi3110_open_clean(net);
> +		goto open_unlock;
> +	}
> +	ret = hi3110_set_normal_mode(spi);
> +	if (ret) {
> +		hi3110_open_clean(net);
> +		goto open_unlock;
> +	}
> +	can_led_event(net, CAN_LED_EVENT_OPEN);
> +	netif_wake_queue(net);
> +
> +open_unlock:
> +	mutex_unlock(&priv->hi3110_lock);
> +	return ret;
> +}
> +
> +static const struct net_device_ops hi3110_netdev_ops = {
> +	.ndo_open = hi3110_open,
> +	.ndo_stop = hi3110_stop,
> +	.ndo_start_xmit = hi3110_hard_start_xmit,
> +};
> +
> +static const struct of_device_id hi3110_of_match[] = {
> +	{
> +		.compatible	= "holt,hi3110",
> +		.data		= (void *)CAN_HI3110_HI3110,
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, hi3110_of_match);
> +
> +static const struct spi_device_id hi3110_id_table[] = {
> +	{
> +		.name		= "hi3110",
> +		.driver_data	= (kernel_ulong_t)CAN_HI3110_HI3110,
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(spi, hi3110_id_table);
> +
> +static int hi3110_can_probe(struct spi_device *spi)
> +{
> +	const struct of_device_id *of_id = of_match_device(hi3110_of_match,
> +							   &spi->dev);
> +	struct net_device *net;
> +	struct hi3110_priv *priv;
> +	struct clk *clk;
> +	int freq, ret;
> +
> +	clk = devm_clk_get(&spi->dev, NULL);
> +	if (IS_ERR(clk)) {
> +		dev_err(&spi->dev, "no CAN clock source defined\n");
> +		return PTR_ERR(clk);
> +	}
> +	freq = clk_get_rate(clk);
> +
> +	/* Sanity check */
> +	if (freq > 40000000)
> +		return -ERANGE;
> +
> +	/* Allocate can/net device */
> +	net = alloc_candev(sizeof(struct hi3110_priv), TX_ECHO_SKB_MAX);
> +	if (!net)
> +		return -ENOMEM;
> +
> +	if (!IS_ERR(clk)) {
> +		ret = clk_prepare_enable(clk);
> +		if (ret)
> +			goto out_free;
> +	}
> +
> +	net->netdev_ops = &hi3110_netdev_ops;
> +	net->flags |= IFF_ECHO;
> +
> +	priv = netdev_priv(net);
> +	priv->can.bittiming_const = &hi3110_bittiming_const;
> +	priv->can.do_set_mode = hi3110_do_set_mode;
> +	priv->can.clock.freq = freq / 2;
> +	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
> +		CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
> +	if (of_id)
> +		priv->model = (enum hi3110_model)of_id->data;
> +	else
> +		priv->model = spi_get_device_id(spi)->driver_data;
> +	priv->net = net;
> +	priv->clk = clk;
> +
> +	spi_set_drvdata(spi, priv);
> +
> +	/* Configure the SPI bus */
> +	spi->bits_per_word = 8;
> +	ret = spi_setup(spi);
> +	if (ret)
> +		goto out_clk;
> +
> +	priv->power = devm_regulator_get_optional(&spi->dev, "vdd");
> +	priv->transceiver = devm_regulator_get_optional(&spi->dev, "xceiver");
> +	if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
> +	    (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) {
> +		ret = -EPROBE_DEFER;
> +		goto out_clk;
> +	}
> +
> +	ret = hi3110_power_enable(priv->power, 1);
> +	if (ret)
> +		goto out_clk;
> +
> +	priv->spi = spi;
> +	mutex_init(&priv->hi3110_lock);
> +
> +	/* If requested, allocate DMA buffers */
> +	if (hi3110_enable_dma) {
> +		spi->dev.coherent_dma_mask = ~0;
> +
> +		/* Minimum coherent DMA allocation is PAGE_SIZE, so allocate
> +		 * that much and share it between Tx and Rx DMA buffers.
> +		 */
> +		priv->spi_tx_buf = dmam_alloc_coherent(&spi->dev,
> +						      PAGE_SIZE,
> +						      &priv->spi_tx_dma,
> +						      GFP_DMA);
> +
> +		if (priv->spi_tx_buf) {
> +			priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2));
> +			priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma +
> +							(PAGE_SIZE / 2));
> +		} else {
> +			/* Fall back to non-DMA */
> +			hi3110_enable_dma = 0;
> +		}
> +	}
> +
> +	/* Allocate non-DMA buffers */
> +	if (!hi3110_enable_dma) {
> +		priv->spi_tx_buf = devm_kzalloc(&spi->dev, RX_BUF_LEN,
> +				GFP_KERNEL);
> +		if (!priv->spi_tx_buf) {
> +			ret = -ENOMEM;
> +			goto error_probe;
> +		}
> +		priv->spi_rx_buf = devm_kzalloc(&spi->dev, RX_BUF_LEN,
> +				GFP_KERNEL);
> +
> +		if (!priv->spi_rx_buf) {
> +			ret = -ENOMEM;
> +			goto error_probe;
> +		}
> +	}
> +
> +	SET_NETDEV_DEV(net, &spi->dev);
> +
> +	ret = hi3110_hw_probe(spi);
> +	if (ret) {
> +		if (ret == -ENODEV)
> +			dev_err(&spi->dev, "Cannot initialize %x. Wrong wiring?\n",
> +				priv->model);
> +		goto error_probe;
> +	}
> +	hi3110_hw_sleep(spi);
> +
> +	ret = register_candev(net);
> +	if (ret)
> +		goto error_probe;
> +
> +	devm_can_led_init(net);
> +	netdev_info(net, "%x successfully initialized.\n", priv->model);
> +
> +	return 0;
> +
> +error_probe:
> +	hi3110_power_enable(priv->power, 0);
> +
> +out_clk:
> +	if (!IS_ERR(clk))
> +		clk_disable_unprepare(clk);
> +
> +out_free:
> +	free_candev(net);
> +
> +	dev_err(&spi->dev, "Probe failed, err=%d\n", -ret);
> +	return ret;
> +}
> +
> +static int hi3110_can_remove(struct spi_device *spi)
> +{
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +	struct net_device *net = priv->net;
> +
> +	unregister_candev(net);
> +
> +	hi3110_power_enable(priv->power, 0);
> +
> +	if (!IS_ERR(priv->clk))
> +		clk_disable_unprepare(priv->clk);
> +
> +	free_candev(net);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused hi3110_can_suspend(struct device *dev)
> +{
> +	struct spi_device *spi = to_spi_device(dev);
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +	struct net_device *net = priv->net;
> +
> +	priv->force_quit = 1;
> +	disable_irq(spi->irq);
> +
> +	/* Note: at this point neither IST nor workqueues are running.
> +	 * open/stop cannot be called anyway so locking is not needed
> +	 */
> +	if (netif_running(net)) {
> +		netif_device_detach(net);
> +
> +		hi3110_hw_sleep(spi);
> +		hi3110_power_enable(priv->transceiver, 0);
> +		priv->after_suspend = AFTER_SUSPEND_UP;
> +	} else {
> +		priv->after_suspend = AFTER_SUSPEND_DOWN;
> +	}
> +
> +	if (!IS_ERR_OR_NULL(priv->power)) {
> +		regulator_disable(priv->power);
> +		priv->after_suspend |= AFTER_SUSPEND_POWER;
> +	}
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused hi3110_can_resume(struct device *dev)
> +{
> +	struct spi_device *spi = to_spi_device(dev);
> +	struct hi3110_priv *priv = spi_get_drvdata(spi);
> +
> +	if (priv->after_suspend & AFTER_SUSPEND_POWER)
> +		hi3110_power_enable(priv->power, 1);
> +
> +	if (priv->after_suspend & AFTER_SUSPEND_UP) {
> +		hi3110_power_enable(priv->transceiver, 1);
> +		queue_work(priv->wq, &priv->restart_work);
> +	} else {
> +		priv->after_suspend = 0;
> +	}
> +
> +	priv->force_quit = 0;
> +	enable_irq(spi->irq);
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(hi3110_can_pm_ops, hi3110_can_suspend,
> +	hi3110_can_resume);
> +
> +static struct spi_driver hi3110_can_driver = {
> +	.driver = {
> +		.name = DEVICE_NAME,
> +		.of_match_table = hi3110_of_match,
> +		.pm = &hi3110_can_pm_ops,
> +	},
> +	.id_table = hi3110_id_table,
> +	.probe = hi3110_can_probe,
> +	.remove = hi3110_can_remove,
> +};
> +
> +module_spi_driver(hi3110_can_driver);
> +
> +MODULE_AUTHOR("Akshay Bhat <akshay.bhat@timesys.com>");
> +MODULE_AUTHOR("Casey Fitzpatrick <casey.fitzpatrick@timesys.com>");
> +MODULE_DESCRIPTION("Holt HI-3110 CAN driver");
> +MODULE_LICENSE("GPL v2");
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH 3/5] mfd: twl: move structure definitions to a public header
From: Lee Jones @ 2017-01-03 15:40 UTC (permalink / raw)
  To: Nicolae Rosia
  Cc: Mark Rutland, devicetree, Baruch Siach, Tony Lindgren,
	Liam Girdwood, Rob Herring, linux-kernel, Paul Gortmaker,
	Mark Brown, Graeme Gregory, linux-omap, linux-arm-kernel
In-Reply-To: <20161126181326.14951-4-Nicolae_Rosia@mentor.com>

On Sat, 26 Nov 2016, Nicolae Rosia wrote:

> We want to get rid of exported symbols and have
> the child devices use structure members directly.
> Move the structure definitions to header and set
> drvdata so child devices can access it.

  < Please use all 75 chars allocated to the commitlog before line wrapping >

> Signed-off-by: Nicolae Rosia <Nicolae_Rosia@mentor.com>
> ---
>  drivers/mfd/twl-core.c       | 27 ++++-----------------------
>  include/linux/mfd/twl-core.h | 35 +++++++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+), 23 deletions(-)
>  create mode 100644 include/linux/mfd/twl-core.h
> 
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index e16084e..409b836 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -48,6 +48,7 @@
>  
>  #include <linux/i2c.h>
>  #include <linux/i2c/twl.h>
> +#include <linux/mfd/twl-core.h>
>  
>  /* Register descriptions for audio */
>  #include <linux/mfd/twl4030-audio.h>
> @@ -154,28 +155,7 @@ int twl4030_init_irq(struct device *dev, int irq_num);
>  int twl4030_exit_irq(void);
>  int twl4030_init_chip_irq(const char *chip);
>  
> -/* Structure for each TWL4030/TWL6030 Slave */
> -struct twl_client {
> -	struct i2c_client *client;
> -	struct regmap *regmap;
> -};
> -
> -/* mapping the module id to slave id and base address */
> -struct twl_mapping {
> -	unsigned char sid;	/* Slave ID */
> -	unsigned char base;	/* base address */
> -};
> -
> -struct twl_private {
> -	bool ready; /* The core driver is ready to be used */
> -	u32 twl_idcode; /* TWL IDCODE Register value */
> -	unsigned int twl_id;
> -
> -	struct twl_mapping *twl_map;
> -	struct twl_client *twl_modules;
> -};
> -
> -static struct twl_private *twl_priv;
> +static struct twlcore *twl_priv;

I'm guessing when you remove the exported functions, you can remove this?

>  static struct twl_mapping twl4030_map[] = {
>  	/*
> @@ -745,7 +725,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  		goto free;
>  	}
>  
> -	twl_priv = devm_kzalloc(&client->dev, sizeof(struct twl_private),
> +	twl_priv = devm_kzalloc(&client->dev, sizeof(struct twlcore),
>  				GFP_KERNEL);
>  	if (!twl_priv) {
>  		status = -ENOMEM;
> @@ -803,6 +783,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  	}
>  
>  	twl_priv->ready = true;
> +	dev_set_drvdata(&client->dev, twl_priv);
>  
>  	/* setup clock framework */
>  	clocks_init(&pdev->dev);
> diff --git a/include/linux/mfd/twl-core.h b/include/linux/mfd/twl-core.h
> new file mode 100644
> index 0000000..d1c01b3
> --- /dev/null
> +++ b/include/linux/mfd/twl-core.h
> @@ -0,0 +1,35 @@
> +/*
> + * MFD core driver for the Texas Instruments TWL PMIC family
> + *
> + * Copyright (C) 2016 Nicolae Rosia <nicolae.rosia@gmail.com>

Your sign-off and SoB are different?  Why?

> + * 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.
> + */
> +
> +#ifndef __TWL_CORE_H__
> +#define __TWL_CORE_H__

_MFD_

> +/* Structure for each TWL4030/TWL6030 Slave */
> +struct twl_client {
> +	struct i2c_client *client;
> +	struct regmap *regmap;
> +};
> +
> +/* mapping the module id to slave id and base address */
> +struct twl_mapping {
> +	unsigned char sid; /* Slave ID */
> +	unsigned char base; /* base address */
> +};
> +
> +struct twlcore {
> +	bool ready; /* The core driver is ready to be used */
> +	u32 twl_idcode; /* TWL IDCODE Register value */
> +	unsigned int twl_id;
> +
> +	struct twl_mapping *twl_map;
> +	struct twl_client *twl_modules;
> +};
> +
> +#endif

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 5/5] mfd: twl: use mfd_add_devices for TWL6032 regulator
From: Lee Jones @ 2017-01-03 15:46 UTC (permalink / raw)
  To: Nicolae Rosia
  Cc: Mark Rutland, devicetree, Baruch Siach, Tony Lindgren,
	Liam Girdwood, Rob Herring, linux-kernel, Paul Gortmaker,
	Mark Brown, Graeme Gregory, linux-omap, linux-arm-kernel
In-Reply-To: <20161126181326.14951-6-Nicolae_Rosia@mentor.com>

On Sat, 26 Nov 2016, Nicolae Rosia wrote:

> TWL6032 regulator driver uses the drvdata twl_priv pointer.
> In order to avoid accessing an invalid drvdata
> when the driver gets unbinded, make sure we remove the
> child devices before deleting the drvdata.

This doesn't really describe the change.

Surely we're really just registering the regulator driver?

The fact that we then remove the device during .remove() is
incidental. 

> Signed-off-by: Nicolae Rosia <Nicolae_Rosia@mentor.com>
> ---
>  drivers/mfd/twl-core.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index 409b836..1e94364 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -43,6 +43,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
> +#include <linux/mfd/core.h>
>  
>  #include <linux/regulator/machine.h>
>  
> @@ -155,8 +156,16 @@ int twl4030_init_irq(struct device *dev, int irq_num);
>  int twl4030_exit_irq(void);
>  int twl4030_init_chip_irq(const char *chip);
>  
> +

?

>  static struct twlcore *twl_priv;
>  
> +static struct mfd_cell twl6032_devs[] = {
> +	{
> +		.name = "twl6032-regulator",
> +		.of_compatible = "ti,twl6032-regulator",
> +	},
> +};
> +
>  static struct twl_mapping twl4030_map[] = {
>  	/*
>  	 * NOTE:  don't change this table without updating the
> @@ -665,6 +674,8 @@ static int twl_remove(struct i2c_client *client)
>  	unsigned i, num_slaves;
>  	int status;
>  
> +	mfd_remove_devices(&client->dev);
> +
>  	if (twl_class_is_4030())
>  		status = twl4030_exit_irq();
>  	else
> @@ -834,6 +845,17 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  				 TWL4030_DCDC_GLOBAL_CFG);
>  	}
>  
> +	if (id->driver_data & TWL6032_SUBCLASS) {
> +		status = mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
> +					 twl6032_devs, ARRAY_SIZE(twl6032_devs),
> +					 NULL, 0, NULL);
> +		if (status != 0) {
> +			dev_err(&client->dev, "failed to add mfd devices: %d\n",
> +				status);
> +			goto fail;
> +		}
> +	}
> +
>  fail:
>  	if (status < 0)
>  		twl_remove(client);

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 2/8] ARM: dts: armada-38x: Utilize new DSA binding
From: Gregory CLEMENT @ 2017-01-03 16:14 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, vivien.didelot,
	Russell King, open list,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20170102022249.10657-3-f.fainelli@gmail.com>

Hi Florian,

You should use the board name in the topic, ie:
"ARM: dts: armada-385-linksys: Utilize new DSA binding"

Thanks,

Gregory


 On lun., janv. 02 2017, Florian Fainelli <f.fainelli@gmail.com> wrote:

> Utilize the new DSA binding, introduced with commit 8c5ad1d6179d ("net: dsa:
> Document new binding"). The legacy binding node is kept included, but is marked
> disabled.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  arch/arm/boot/dts/armada-385-linksys.dtsi | 52 ++++++++++++++++++++++++++++++-
>  1 file changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi
> index 8f0e508f64ae..20d5e8b00f2d 100644
> --- a/arch/arm/boot/dts/armada-385-linksys.dtsi
> +++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
> @@ -103,8 +103,56 @@
>  				};
>  			};
>  
> -			mdio {
> +			mdio@72004 {
>  				status = "okay";
> +
> +				switch@0 {
> +					compatible = "marvell,mv88e6095";
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +					reg = <0>;
> +
> +					ports {
> +						#address-cells = <1>;
> +						#size-cells = <0>;
> +
> +						port@0 {
> +							reg = <0>;
> +							label = "lan4";
> +						};
> +
> +						port@1 {
> +							reg = <1>;
> +							label = "lan3";
> +						};
> +
> +						port@2 {
> +							reg = <2>;
> +							label = "lan2";
> +						};
> +
> +						port@3 {
> +							reg = <3>;
> +							label = "lan1";
> +						};
> +
> +						port@4 {
> +							reg = <4>;
> +							label = "wan";
> +						};
> +
> +						port@5 {
> +							reg = <5>;
> +							label = "cpu";
> +							ethernet = <&eth2>;
> +
> +							fixed-link {
> +								speed = <1000>;
> +								full-duplex;
> +							};
> +						};
> +					};
> +				};
>  			};
>  
>  			sata@a8000 {
> @@ -261,6 +309,8 @@
>  	};
>  
>  	dsa@0 {
> +		status = "disabled";
> +
>  		compatible = "marvell,dsa";
>  		#address-cells = <2>;
>  		#size-cells = <0>;
> -- 
> 2.9.3
>

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH 0/8] ARM: dts: Switch to new DSA binding
From: Gregory CLEMENT @ 2017-01-03 16:19 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, vivien.didelot,
	Russell King, open list,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20170102022249.10657-1-f.fainelli@gmail.com>

Hi Florian,
 
 On lun., janv. 02 2017, Florian Fainelli <f.fainelli@gmail.com> wrote:

> Hi all,
>
> This patch series converts the in-tree users to utilize the new (relatively)
> DSA binding that was introduced with commit 8c5ad1d6179d ("net: dsa: Document
> new binding"). The legacy binding node is kept included, but is marked
> disabled.
>
> In about 2-3 releases we may consider removing the old DSA binding entirely
> from the kernel.

The series looks OK. However I would like to have a reviewed by from
Andrew who know well the mvebu platform and the DSA subsystem.

Also there's few fixes needed for the v2.

Thanks,

Gregory

>
> Thank you!
>
> Florian Fainelli (8):
>   ARM: dts: armada-370-rd: Utilize new DSA binding
>   ARM: dts: armada-38x: Utilize new DSA binding
>   ARM: dts: armada-388-clearfog: Utilize new DSA binding
>   ARM: dts: armada-xp-linksys-mamba: Utilize new DSA binding
>   ARM: dts: kirkwood-dir665: Utilize new DSA binding
>   ARM: dts: kirkwood-linksys-viper: Utilize new DSA binding
>   ARM: dts: kirkwood-mv88f6281gtw-ge: Utilize new DSA binding
>   ARM: dts: kirkwood-rd88f6281: Utilize new DSA binding
>
>  arch/arm/boot/dts/armada-370-rd.dts            | 44 +++++++++++++++++
>  arch/arm/boot/dts/armada-385-linksys.dtsi      | 52 ++++++++++++++++++++-
>  arch/arm/boot/dts/armada-388-clearfog.dts      | 65 ++++++++++++++++++++++++++
>  arch/arm/boot/dts/armada-xp-linksys-mamba.dts  | 53 +++++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-dir665.dts          | 49 +++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-linksys-viper.dts   | 49 +++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 49 +++++++++++++++++++
>  arch/arm/boot/dts/kirkwood-rd88f6281-z0.dts    | 11 +++++
>  arch/arm/boot/dts/kirkwood-rd88f6281.dtsi      | 44 +++++++++++++++++
>  9 files changed, 415 insertions(+), 1 deletion(-)
>
> -- 
> 2.9.3
>

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH 3/4] arm64: dts: exynos: make tm2 and tm2e independent from each other
From: Krzysztof Kozlowski @ 2017-01-03 16:31 UTC (permalink / raw)
  To: Chanwoo Choi
  Cc: Mark Rutland, devicetree, linux-samsung-soc, Kukjin Kim,
	Chanwoo Choi, Catalin Marinas, Jaechul Lee, Dmitry Torokhov,
	Will Deacon, linux-kernel, Andi Shyti, Javier Martinez Canillas,
	Rob Herring, Krzysztof Kozlowski, Andi Shyti, linux-input,
	galaxyra, beomho.seo, linux-arm-kernel
In-Reply-To: <CAGTfZH0tnjkqF_7DChLSvzs3C369mkb_HZmyrf3cc0T-UcBZ4A@mail.gmail.com>

On Wed, Jan 04, 2017 at 12:29:23AM +0900, Chanwoo Choi wrote:
> Hi Andi,
> 
> 2017-01-03 23:40 GMT+09:00 Andi Shyti <andi@etezian.org>:
> > Hi,
> >
> >> FWIW, I also agree with Chanwoo that the difference is too small to
> >> need a common .dtsi file.
> >
> > in principle I don't like "switching on and off" properties by
> > overwriting them with "status = disable", unless it's really
> > necessary (and this case is not). Even for small differences. It
> > makes the DTS harder to read and duplicates nodes with different
> > values throughout the DTS include chain.

I agree.

> >
> > In my opinion this approach should be discouraged.
> >
> > Besides, there are other overwritten differences in tm2e.dts that
> > I think should be separated as well. The "common" file approach is
> > widely used in arm/boot/dts/exynos* files.

I agree. Mostly we use:
1. Common DTSI and final addons/customizations in DTS.
2. Several common DTSI for specific parts (like sound).

> > The "status = disable" looks to me more like a temporary hack
> > rather than a permanent solution.
> >
> > In any case, still up to you :)
> >
> > Andi
> 
> I think that "status=disabled" of hsi2c_9 is not hack. The overwrite
> is possible for Device-tree. But, there is just difference how to
> support them with some method.
> 
> Except for touchkey, all peripheral device are same on both tm2 and
> tm2e. There are only small difference for a few property value.
> 
> To understand the difference between tm2 and tm2e, I made the patch
> (it is not complete version). If we implement the following patch, we
> support both tm2 and tm2e. So, I think that it is not complex to
> understand the h/w difference between tm2 and tm2e.

The difference below (I removed it from the quote) is indeed very small,
thanks Chanwoo for pointing this. However having common DTSI should not
end with much bigger final diff between files. I mean that it should be
the same amount of lines in total...

Actually, after applying this patch, the final exynos5433-tm2e.dts is
exactly the same as before. To me, this is a indication that a common
file is a good approach.


>From a separate Javier's mail:
> On 01/03/2017 11:40 AM, Andi Shyti wrote:
> > Hi,
> > 
> >> FWIW, I also agree with Chanwoo that the difference is too small to
> >> need a common .dtsi file.
> > 
> > in principle I don't like "switching on and off" properties by
> > overwriting them with "status = disable", unless it's really
> 
> This is a very good point. It would had been different if it was the
> opposite and tm2e had to enable the device node, but disabling it is
> indeed more confusing.
> On 01/03/2017 11:40 AM, Andi Shyti wrote:
> > Hi,
> > 
> >> FWIW, I also agree with Chanwoo that the difference is too small to
> >> need a common .dtsi file.
> > 
> > in principle I don't like "switching on and off" properties by
> > overwriting them with "status = disable", unless it's really
> 
> This is a very good point. It would had been different if it was the
> opposite and tm2e had to enable the device node, but disabling it is
> indeed more confusing.

I agree, 'status = disable' in final DTS is not a common pattern and
to me when reading, it makes me wonder what was the author's intention.

Also including a DTS in DTS is not a common pattern, neither. It appears
(git grep include arch/arm/boot/dts | grep 'dts"') in few places but it
is not obvious. At least to me.

Overall, I prefer the common approach.

Best regards,
Krzysztof

^ 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