* [PATCH v3 1/5] dt-bindings: update device tree binding for Allwinner PRCM CCUs
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>
From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
Many Allwinner SoCs after A31 have a CCU in PRCM block.
Give the ones on H3 and A64 compatible strings.
Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Removed frequency info of iosc in this device tree binding document.
Changes in v2:
- Add iosc for R_CCU's on H3/A64.
Documentation/devicetree/bindings/clock/sunxi-ccu.txt | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index 68512aa398a9..e9c5a1d9834a 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -7,9 +7,11 @@ Required properties :
- "allwinner,sun8i-a23-ccu"
- "allwinner,sun8i-a33-ccu"
- "allwinner,sun8i-h3-ccu"
+ - "allwinner,sun8i-h3-r-ccu"
- "allwinner,sun8i-v3s-ccu"
- "allwinner,sun9i-a80-ccu"
- "allwinner,sun50i-a64-ccu"
+ - "allwinner,sun50i-a64-r-ccu"
- "allwinner,sun50i-h5-ccu"
- reg: Must contain the registers base address and length
@@ -20,7 +22,10 @@ Required properties :
- #clock-cells : must contain 1
- #reset-cells : must contain 1
-Example:
+For the PRCM CCUs on H3/A64, one more clock is needed:
+- "iosc": the SoC's internal frequency oscillator
+
+Example for generic CCU:
ccu: clock@01c20000 {
compatible = "allwinner,sun8i-h3-ccu";
reg = <0x01c20000 0x400>;
@@ -29,3 +34,13 @@ ccu: clock@01c20000 {
#clock-cells = <1>;
#reset-cells = <1>;
};
+
+Example for PRCM CCU:
+r_ccu: clock@01f01400 {
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+};
--
2.12.0
^ permalink raw reply related
* [PATCH v3 2/5] clk: sunxi-ng: add support for PRCM CCUs
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>
From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
SoCs after A31 has a clock controller module in the PRCM part.
Support the clock controller module on H3/5 and A64 now.
Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Change osc32000 mux to iosc, as its frequency varies between SoCs. (And
none of them is really 32000Hz)
Changes in v2:
- Replace all sun6i to sun8i, as this driver currently doesn't really
support sun6i(A31).
- Add osc32000 mux for ar100 clk. (Note: the frequency is proven to be wrong
during the development of PATCH v3).
- Rename some clocks.
- Add gate of TWD (Trusted Watchdog). There's no reset for TWD.
- Removed reset of PIO, which doesn't exist really.
drivers/clk/sunxi-ng/Kconfig | 6 +
drivers/clk/sunxi-ng/Makefile | 1 +
drivers/clk/sunxi-ng/ccu-sun8i-r.c | 211 ++++++++++++++++++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun8i-r.h | 27 ++++
include/dt-bindings/clock/sun8i-r-ccu.h | 59 +++++++++
include/dt-bindings/reset/sun8i-r-ccu.h | 53 ++++++++
6 files changed, 357 insertions(+)
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.c
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.h
create mode 100644 include/dt-bindings/clock/sun8i-r-ccu.h
create mode 100644 include/dt-bindings/reset/sun8i-r-ccu.h
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 8af8f4be8e3b..fbd3f8cd5c22 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -151,4 +151,10 @@ config SUN9I_A80_CCU
default MACH_SUN9I
depends on MACH_SUN9I || COMPILE_TEST
+config SUN8I_R_CCU
+ bool "Support for Allwinner SoCs' PRCM CCUs"
+ select SUNXI_CCU_DIV
+ select SUNXI_CCU_GATE
+ default MACH_SUN8I || (ARCH_SUNXI && ARM64)
+
endif
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 6feaac0c5600..0ec02fe14c50 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -25,6 +25,7 @@ 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
+obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
new file mode 100644
index 000000000000..ddbb34018086
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * 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 <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun8i-r.h"
+
+static const char * const ar100_parents[] = { "osc32k", "osc24M",
+ "pll-periph0", "iosc" };
+
+static struct ccu_div ar100_clk = {
+ .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+ .mux = {
+ .shift = 16,
+ .width = 2,
+
+ .variable_prediv = {
+ .index = 2,
+ .shift = 8,
+ .width = 5,
+ },
+ },
+
+ .common = {
+ .reg = 0x00,
+ .features = CCU_FEATURE_VARIABLE_PREDIV,
+ .hw.init = CLK_HW_INIT_PARENTS("ar100",
+ ar100_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
+
+static struct ccu_div apb0_clk = {
+ .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+ .common = {
+ .reg = 0x0c,
+ .hw.init = CLK_HW_INIT("apb0",
+ "ahb0",
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0",
+ 0x28, BIT(0), 0);
+static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0",
+ 0x28, BIT(1), 0);
+static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0",
+ 0x28, BIT(2), 0);
+static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0",
+ 0x28, BIT(3), 0);
+static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0",
+ 0x28, BIT(4), 0);
+static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0",
+ 0x28, BIT(6), 0);
+static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0",
+ 0x28, BIT(7), 0);
+
+static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
+ r_mod0_default_parents, 0x54,
+ 0, 4, /* M */
+ 16, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static struct ccu_common *sun8i_h3_r_ccu_clks[] = {
+ &ar100_clk.common,
+ &apb0_clk.common,
+ &apb0_pio_clk.common,
+ &apb0_ir_clk.common,
+ &apb0_timer_clk.common,
+ &apb0_uart_clk.common,
+ &apb0_i2c_clk.common,
+ &ir_clk.common,
+};
+
+static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
+ &ar100_clk.common,
+ &apb0_clk.common,
+ &apb0_pio_clk.common,
+ &apb0_ir_clk.common,
+ &apb0_timer_clk.common,
+ &apb0_rsb_clk.common,
+ &apb0_uart_clk.common,
+ &apb0_i2c_clk.common,
+ &ir_clk.common,
+};
+
+static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = {
+ .hws = {
+ [CLK_AR100] = &ar100_clk.common.hw,
+ [CLK_AHB0] = &ahb0_clk.hw,
+ [CLK_APB0] = &apb0_clk.common.hw,
+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw,
+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw,
+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw,
+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw,
+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw,
+ [CLK_IR] = &ir_clk.common.hw,
+ },
+ .num = CLK_NUMBER,
+};
+
+static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = {
+ .hws = {
+ [CLK_AR100] = &ar100_clk.common.hw,
+ [CLK_AHB0] = &ahb0_clk.hw,
+ [CLK_APB0] = &apb0_clk.common.hw,
+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw,
+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw,
+ [CLK_APB0_RSB] = &apb0_rsb_clk.common.hw,
+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw,
+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw,
+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw,
+ [CLK_IR] = &ir_clk.common.hw,
+ },
+ .num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = {
+ [RST_APB0_IR] = { 0xb0, BIT(1) },
+ [RST_APB0_TIMER] = { 0xb0, BIT(2) },
+ [RST_APB0_UART] = { 0xb0, BIT(4) },
+ [RST_APB0_I2C] = { 0xb0, BIT(6) },
+};
+
+static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = {
+ [RST_APB0_IR] = { 0xb0, BIT(1) },
+ [RST_APB0_TIMER] = { 0xb0, BIT(2) },
+ [RST_APB0_RSB] = { 0xb0, BIT(3) },
+ [RST_APB0_UART] = { 0xb0, BIT(4) },
+ [RST_APB0_I2C] = { 0xb0, BIT(6) },
+};
+
+static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = {
+ .ccu_clks = sun8i_h3_r_ccu_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun8i_h3_r_ccu_clks),
+
+ .hw_clks = &sun8i_h3_r_hw_clks,
+
+ .resets = sun8i_h3_r_ccu_resets,
+ .num_resets = ARRAY_SIZE(sun8i_h3_r_ccu_resets),
+};
+
+static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
+ .ccu_clks = sun50i_a64_r_ccu_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun50i_a64_r_ccu_clks),
+
+ .hw_clks = &sun50i_a64_r_hw_clks,
+
+ .resets = sun50i_a64_r_ccu_resets,
+ .num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets),
+};
+
+static void __init sunxi_r_ccu_init(struct device_node *node,
+ const struct sunxi_ccu_desc *desc)
+{
+ void __iomem *reg;
+
+ 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;
+ }
+
+ sunxi_ccu_probe(node, reg, desc);
+}
+
+static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
+{
+ sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
+}
+CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
+ sun8i_h3_r_ccu_setup);
+
+static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
+{
+ sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
+}
+CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
+ sun50i_a64_r_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
new file mode 100644
index 000000000000..eaa431fd1d8f
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 Icenowy <icenowy-ymACFijhrKM@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_R_H
+#define _CCU_SUN8I_R_H_
+
+#include <dt-bindings/clock/sun8i-r-ccu.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
+
+/* AHB/APB bus clocks are not exported */
+#define CLK_AHB0 1
+#define CLK_APB0 2
+
+#define CLK_NUMBER (CLK_APB0_TWD + 1)
+
+#endif /* _CCU_SUN8I_R_H */
diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h
new file mode 100644
index 000000000000..779d20aa0d05
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-r-ccu.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
+
+#define CLK_AR100 0
+
+#define CLK_APB0_PIO 3
+#define CLK_APB0_IR 4
+#define CLK_APB0_TIMER 5
+#define CLK_APB0_RSB 6
+#define CLK_APB0_UART 7
+/* 8 is reserved for CLK_APB0_W1 on A31 */
+#define CLK_APB0_I2C 9
+#define CLK_APB0_TWD 10
+
+#define CLK_IR 11
+
+#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h
new file mode 100644
index 000000000000..4ba64f3d6fc9
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-r-ccu.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_
+
+#define RST_APB0_IR 0
+#define RST_APB0_TIMER 1
+#define RST_APB0_RSB 2
+#define RST_APB0_UART 3
+/* 4 is reserved for RST_APB0_W1 on A31 */
+#define RST_APB0_I2C 5
+
+#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */
--
2.12.0
^ permalink raw reply related
* [PATCH v3 3/5] arm64: allwinner: a64: add r_ccu node
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>
From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
A64 SoC have a CCU (r_ccu) in PRCM block.
Add the device node for it.
The mux 3 of R_CCU is an internal oscillator, which is 16MHz according
to the user manual, and has only 30% accuracy based on our experience
on older SoCs. The real mesaured value of it on two Pine64 boards is
around 11MHz, which is around 70% of 16MHz.
Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Change osc32000 to iosc, which is 16MHz plus minus 30%, according to the
RTC chapter of the user manual and our experiences on A33.
Changes in v2:
- Add osc32000.
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 1c64ea2d23f9..0fe9865d4bd6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -43,8 +43,10 @@
*/
#include <dt-bindings/clock/sun50i-a64-ccu.h>
+#include <dt-bindings/clock/sun8i-r-ccu.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/sun50i-a64-ccu.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
/ {
interrupt-parent = <&gic>;
@@ -98,6 +100,14 @@
clock-output-names = "osc32k";
};
+ iosc: internal-osc-clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
+ };
+
psci {
compatible = "arm,psci-0.2";
method = "smc";
@@ -392,5 +402,14 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
+
+ r_ccu: clock@1f01400 {
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
};
};
--
2.12.0
^ permalink raw reply related
* [PATCH v3 4/5] ARM: sunxi: h3/h5: switch apb0-related clocks to r_ccu
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>
From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .
The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.
Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Change osc32000 to iosc.
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 47 +++++++++++++-------------------------
1 file changed, 16 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..a7e858a82c90 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -41,8 +41,10 @@
*/
#include <dt-bindings/clock/sun8i-h3-ccu.h>
+#include <dt-bindings/clock/sun8i-r-ccu.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/sun8i-h3-ccu.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
/ {
interrupt-parent = <&gic>;
@@ -68,31 +70,12 @@
clock-output-names = "osc32k";
};
- apb0: apb0_clk {
- compatible = "fixed-factor-clock";
+ iosc: internal-osc-clk {
#clock-cells = <0>;
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&osc24M>;
- clock-output-names = "apb0";
- };
-
- apb0_gates: clk@01f01428 {
- compatible = "allwinner,sun8i-h3-apb0-gates-clk",
- "allwinner,sun4i-a10-gates-clk";
- reg = <0x01f01428 0x4>;
- #clock-cells = <1>;
- clocks = <&apb0>;
- clock-indices = <0>, <1>;
- clock-output-names = "apb0_pio", "apb0_ir";
- };
-
- ir_clk: ir_clk@01f01454 {
- compatible = "allwinner,sun4i-a10-mod0-clk";
- reg = <0x01f01454 0x4>;
- #clock-cells = <0>;
- clocks = <&osc32k>, <&osc24M>;
- clock-output-names = "ir";
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
};
};
@@ -576,9 +559,12 @@
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
- apb0_reset: reset@01f014b0 {
- reg = <0x01f014b0 0x4>;
- compatible = "allwinner,sun6i-a31-clock-reset";
+ r_ccu: clock@1f01400 {
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
#reset-cells = <1>;
};
@@ -589,9 +575,9 @@
ir: ir@01f02000 {
compatible = "allwinner,sun5i-a13-ir";
- clocks = <&apb0_gates 1>, <&ir_clk>;
+ clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
clock-names = "apb", "ir";
- resets = <&apb0_reset 1>;
+ resets = <&r_ccu RST_APB0_IR>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x40>;
status = "disabled";
@@ -601,9 +587,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
- resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
--
2.12.0
^ permalink raw reply related
* [PATCH v3 5/5] arm64: allwinner: a64: add R_PIO pinctrl node
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>
From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
Allwinner A64 have a dedicated pin controller to manage the PL pin bank.
As the driver and the required clock support are added, add the device
node for it.
Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 0fe9865d4bd6..165dbc848aa6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -411,5 +411,17 @@
#clock-cells = <1>;
#reset-cells = <1>;
};
+
+ r_pio: pinctrl@01f02c00 {
+ compatible = "allwinner,sun50i-a64-r-pinctrl";
+ reg = <0x01f02c00 0x400>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
+ gpio-controller;
+ #gpio-cells = <3>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
};
};
--
2.12.0
^ permalink raw reply related
* Re: [PATCH v7 1/7] clocksource/drivers/clksrc-evt-probe: Describe with the DT both the clocksource and the clockevent
From: Mark Rutland @ 2017-03-29 10:49 UTC (permalink / raw)
To: Daniel Lezcano
Cc: Rob Herring, Alexander Kochetkov, Heiko Stuebner, linux-kernel,
devicetree, linux-arm-kernel, linux-rockchip, Thomas Gleixner,
Russell King, Caesar Wang, Huang Tao
In-Reply-To: <20170329092210.GH2123@mai>
Hi,
On Wed, Mar 29, 2017 at 11:22:10AM +0200, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 08:51:46PM -0500, Rob Herring wrote:
> > On Wed, Mar 22, 2017 at 06:48:28PM +0300, Alexander Kochetkov wrote:
> > > From: Daniel Lezcano <daniel.lezcano@linaro.org>
> > >
> > > The CLOCKSOURCE_OF_DECLARE() was introduced before the
> > > CLOCKEVENT_OF_DECLARE() and that resulted in some abuse where the
> > > clockevent and the clocksource are both initialized in the same init
> > > routine.
> > >
> > > With the introduction of the CLOCKEVENT_OF_DECLARE(), the driver can
> > > now split the clocksource and the clockevent init code. However, the
> > > device tree may specify a single node, so the same node will be passed
> > > to the clockevent/clocksource's init function, with the same base
> > > address.
> > >
> > > with this patch it is possible to specify an attribute to the timer's node to
> > > specify if it is a clocksource or a clockevent and define two timers node.
> >
> > Daniel and I discussed and agreed against this a while back. What
> > changed?
>
> Hi Rob,
>
> > > For example:
> > >
> > > timer: timer@98400000 {
> > > compatible = "moxa,moxart-timer";
> > > reg = <0x98400000 0x42>;
> >
> > This overlaps the next node. You can change this to 0x10, but are these
> > really 2 independent h/w blocks? Don't design the nodes around the
> > current needs of Linux.
>
> Mmh, thanks for raising this. Conceptually speaking there are two (or more)
> different entities, the clocksource and the clockevents but they share the same
> IP block.
>From the DT's PoV, this is one entity, which is the IP block.
The clocksource/clockevent concept is a Linux implementation detail. The
DT cannot and should not be aware of that.
[...]
> > > interrupts = <19 1>;
> > > clocks = <&coreclk>;
> > > clockevent;
> >
> > This is not needed. The presence of "interrupts" is enough to say use
> > this timer for clockevent.
>
> Yes, that is true if no drivers was already taking CLOCKSOURCE_OF and
> initializing the clockevent. The driver will pass through the clocksource_probe
> function, check the interrupt and bail out because there is an interrupt
> declared and assume it is a clockevent, so no initialization for the driver.
> IOW, it is not backward compatible.
>
> We need this attribute somehow in order to separate clearly a clocksource or a
> clockevent with a new implementation.
Why? A single IP block can provide the functionality of both (though
there are reasons that functionality may be mutually exclusive). What is
the benefit of this split?
> > > With this approach, we allow a mechanism to clearly define a clocksource or a
> > > clockevent without aerobatics we can find around in some drivers:
> > > timer-sp804.c, arc-timer.c, dw_apb_timer_of.c, mps2-timer.c,
> > > renesas-ostm.c, time-efm32.c, time-lpc32xx.c.
> >
> > These all already have bindings and work. What problem are you trying to
> > solve other than restructuring Linux?
>
> Yes, there is already the bindings, but that force to do some hackish
> initialization.
Here, you are forcing hackish DT changes that do not truly describe HW.
How is that better?
> I would like to give the opportunity to declare separately a clocksource and a
> clockevent, in order to have full control of how this is initialized.
To me it sounds like what we need is Linux infrastructure that allows
one to register a device as having both clockevent/clocksource
functionality.
That way, we can choose to do something sane at boot time, and if the
user really wants specific devices used in specific ways, they can
request that.
Thanks,
Mark.
^ permalink raw reply
* Re: [PATCH 2/2] mtd: spi-nor: add driver for STM32 quad spi flash controller
From: Marek Vasut @ 2017-03-29 10:54 UTC (permalink / raw)
To: Ludovic Barre, Cyrille Pitchen
Cc: David Woodhouse, Brian Norris, Boris Brezillon,
Richard Weinberger, Alexandre Torgue, Rob Herring,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1490619296-8168-3-git-send-email-ludovic.Barre-qxv4g6HH51o@public.gmane.org>
On 03/27/2017 02:54 PM, Ludovic Barre wrote:
> From: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
>
> The quadspi is a specialized communication interface targeting single,
> dual or quad SPI Flash memories.
>
> It can operate in any of the following modes:
> -indirect mode: all the operations are performed using the quadspi
> registers
> -read memory-mapped mode: the external Flash memory is mapped to the
> microcontroller address space and is seen by the system as if it was
> an internal memory
>
> Signed-off-by: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
Hi! I presume this is not compatible with the Cadence QSPI or any other
QSPI controller, huh ?
Mostly minor nits below ...
> ---
> drivers/mtd/spi-nor/Kconfig | 7 +
> drivers/mtd/spi-nor/Makefile | 1 +
> drivers/mtd/spi-nor/stm32-quadspi.c | 679 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 687 insertions(+)
> create mode 100644 drivers/mtd/spi-nor/stm32-quadspi.c
[...]
> +struct stm32_qspi_cmd {
> + struct {
> + u32 addr_width:8;
> + u32 dummy:8;
> + u32 data:1;
> + } conf;
This could all be u8 ? Why this awful construct ?
> + u8 opcode;
> + u32 framemode;
> + u32 qspimode;
> + u32 addr;
> + size_t len;
> + void *buf;
> +};
> +
> +static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi)
> +{
> + u32 cr;
> + int err = 0;
Can readl_poll_timeout() or somesuch replace this function ?
> + if (readl_relaxed(qspi->io_base + QUADSPI_SR) & SR_TCF)
> + return 0;
> +
> + reinit_completion(&qspi->cmd_completion);
> + cr = readl_relaxed(qspi->io_base + QUADSPI_CR);
> + writel_relaxed(cr | CR_TCIE, qspi->io_base + QUADSPI_CR);
> +
> + if (!wait_for_completion_interruptible_timeout(&qspi->cmd_completion,
> + msecs_to_jiffies(1000)))
> + err = -ETIMEDOUT;
> +
> + writel_relaxed(cr, qspi->io_base + QUADSPI_CR);
> + return err;
> +}
> +
> +static int stm32_qspi_wait_nobusy(struct stm32_qspi *qspi)
> +{
> + u32 sr;
> +
> + return readl_relaxed_poll_timeout(qspi->io_base + QUADSPI_SR, sr,
> + !(sr & SR_BUSY), 10, 100000);
> +}
> +
> +static void stm32_qspi_set_framemode(struct spi_nor *nor,
> + struct stm32_qspi_cmd *cmd, bool read)
> +{
> + u32 dmode = CCR_DMODE_1;
> +
> + cmd->framemode = CCR_IMODE_1;
> +
> + if (read) {
> + switch (nor->flash_read) {
> + case SPI_NOR_NORMAL:
> + case SPI_NOR_FAST:
> + dmode = CCR_DMODE_1;
> + break;
> + case SPI_NOR_DUAL:
> + dmode = CCR_DMODE_2;
> + break;
> + case SPI_NOR_QUAD:
> + dmode = CCR_DMODE_4;
> + break;
> + }
> + }
> +
> + cmd->framemode |= cmd->conf.data ? dmode : 0;
> + cmd->framemode |= cmd->conf.addr_width ? CCR_ADMODE_1 : 0;
> +}
> +
> +static void stm32_qspi_read_fifo(u8 *val, void __iomem *addr)
> +{
> + *val = readb_relaxed(addr);
> +}
> +
> +static void stm32_qspi_write_fifo(u8 *val, void __iomem *addr)
> +{
> + writeb_relaxed(*val, addr);
> +}
> +
> +static int stm32_qspi_tx_poll(struct stm32_qspi *qspi,
> + const struct stm32_qspi_cmd *cmd)
> +{
> + void (*tx_fifo)(u8 *, void __iomem *);
> + u32 len = cmd->len, sr;
> + u8 *buf = cmd->buf;
> + int ret;
> +
> + if (cmd->qspimode == CCR_FMODE_INDW)
> + tx_fifo = stm32_qspi_write_fifo;
> + else
> + tx_fifo = stm32_qspi_read_fifo;
> +
> + while (len--) {
> + ret = readl_relaxed_poll_timeout(qspi->io_base + QUADSPI_SR,
> + sr, (sr & SR_FTF),
> + 10, 30000);
Add macros for those ad-hoc timeouts.
> + if (ret) {
> + dev_err(qspi->dev, "fifo timeout (stat:%#x)\n", sr);
> + break;
> + }
> + tx_fifo(buf++, qspi->io_base + QUADSPI_DR);
> + }
> +
> + return ret;
> +}
[...]
> +static int stm32_qspi_send(struct stm32_qspi_flash *flash,
> + const struct stm32_qspi_cmd *cmd)
> +{
> + struct stm32_qspi *qspi = flash->qspi;
> + u32 ccr, dcr, cr;
> + int err;
> +
> + err = stm32_qspi_wait_nobusy(qspi);
> + if (err)
> + goto abort;
> +
> + dcr = readl_relaxed(qspi->io_base + QUADSPI_DCR) & ~DCR_FSIZE_MASK;
> + dcr |= DCR_FSIZE(flash->fsize);
> + writel_relaxed(dcr, qspi->io_base + QUADSPI_DCR);
> +
> + cr = readl_relaxed(qspi->io_base + QUADSPI_CR);
> + cr &= ~CR_PRESC_MASK & ~CR_FSEL;
> + cr |= CR_PRESC(flash->presc);
> + cr |= flash->cs ? CR_FSEL : 0;
> + writel_relaxed(cr, qspi->io_base + QUADSPI_CR);
> +
> + if (cmd->conf.data)
> + writel_relaxed(cmd->len - 1, qspi->io_base + QUADSPI_DLR);
> +
> + ccr = cmd->framemode | cmd->qspimode;
> +
> + if (cmd->conf.dummy)
> + ccr |= CCR_DCYC(cmd->conf.dummy);
> +
> + if (cmd->conf.addr_width)
> + ccr |= CCR_ADSIZE(cmd->conf.addr_width - 1);
> +
> + ccr |= CCR_INST(cmd->opcode);
> + writel_relaxed(ccr, qspi->io_base + QUADSPI_CCR);
> +
> + if (cmd->conf.addr_width && cmd->qspimode != CCR_FMODE_MM)
> + writel_relaxed(cmd->addr, qspi->io_base + QUADSPI_AR);
> +
> + err = stm32_qspi_tx(qspi, cmd);
> + if (err)
> + goto abort;
> +
> + if (cmd->qspimode != CCR_FMODE_MM) {
> + err = stm32_qspi_wait_cmd(qspi);
> + if (err)
> + goto abort;
> + writel_relaxed(FCR_CTCF, qspi->io_base + QUADSPI_FCR);
> + }
> +
> + return err;
> +
> +abort:
> + writel_relaxed(readl_relaxed(qspi->io_base + QUADSPI_CR)
> + | CR_ABORT, qspi->io_base + QUADSPI_CR);
Use a helper variable here too.
> + dev_err(qspi->dev, "%s abort err:%d\n", __func__, err);
> + return err;
> +}
[...]
> +static int stm32_qspi_flash_setup(struct stm32_qspi *qspi,
> + struct device_node *np)
> +{
> + u32 width, flash_read, presc, cs_num, max_rate = 0;
> + struct stm32_qspi_flash *flash;
> + struct mtd_info *mtd;
> + int ret;
> +
> + of_property_read_u32(np, "reg", &cs_num);
> + if (cs_num >= STM32_MAX_NORCHIP)
> + return -EINVAL;
> +
> + of_property_read_u32(np, "spi-max-frequency", &max_rate);
> + if (!max_rate)
> + return -EINVAL;
> +
> + presc = DIV_ROUND_UP(qspi->clk_rate, max_rate) - 1;
> +
> + if (of_property_read_u32(np, "spi-rx-bus-width", &width))
> + width = 1;
> +
> + if (width == 4)
> + flash_read = SPI_NOR_QUAD;
> + else if (width == 2)
> + flash_read = SPI_NOR_DUAL;
> + else if (width == 1)
> + flash_read = SPI_NOR_NORMAL;
> + else
> + return -EINVAL;
> +
> + flash = &qspi->flash[cs_num];
> + flash->qspi = qspi;
> + flash->cs = cs_num;
> + flash->presc = presc;
> +
> + flash->nor.dev = qspi->dev;
> + spi_nor_set_flash_node(&flash->nor, np);
> + flash->nor.priv = flash;
> + mtd = &flash->nor.mtd;
> + mtd->priv = &flash->nor;
> +
> + flash->nor.read = stm32_qspi_read;
> + flash->nor.write = stm32_qspi_write;
> + flash->nor.erase = stm32_qspi_erase;
> + flash->nor.read_reg = stm32_qspi_read_reg;
> + flash->nor.write_reg = stm32_qspi_write_reg;
> + flash->nor.prepare = stm32_qspi_prep;
> + flash->nor.unprepare = stm32_qspi_unprep;
> +
> + writel_relaxed(LPTR_DFT_TIMEOUT, qspi->io_base + QUADSPI_LPTR);
> +
> + writel_relaxed(CR_PRESC(presc) | CR_FTHRES(3) | CR_TCEN | CR_SSHIFT
> + | CR_EN, qspi->io_base + QUADSPI_CR);
> +
> + /* a minimum fsize must be set to sent the command id */
> + flash->fsize = 25;
I don't understand why this is needed and the comment doesn't make
sense. Please fix.
> + ret = spi_nor_scan(&flash->nor, NULL, flash_read);
> + if (ret) {
> + dev_err(qspi->dev, "device scan failed\n");
> + return ret;
> + }
> +
> + flash->fsize = __fls(mtd->size) - 1;
> +
> + writel_relaxed(DCR_CSHT(1), qspi->io_base + QUADSPI_DCR);
> +
> + ret = mtd_device_register(mtd, NULL, 0);
> + if (ret) {
> + dev_err(qspi->dev, "mtd device parse failed\n");
> + return ret;
> + }
> +
> + dev_dbg(qspi->dev, "read mm:%s cs:%d bus:%d\n",
> + qspi->read_mode == CCR_FMODE_MM ? "yes" : "no", cs_num, width);
> +
> + return 0;
> +}
[...]
--
Best regards,
Marek Vasut
--
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 v6 2/5] irqchip/aspeed-i2c-ic: Add I2C IRQ controller for Aspeed
From: Marc Zyngier @ 2017-03-29 10:55 UTC (permalink / raw)
To: Brendan Higgins, Benjamin Herrenschmidt
Cc: Wolfram Sang, robh+dt, mark.rutland, tglx, jason, Joel Stanley,
Vladimir Zapolskiy, Kachalov Anton, Cédric Le Goater,
linux-i2c, devicetree, linux-kernel, OpenBMC Maillist
In-Reply-To: <CAFd5g46TAGHWtH7p1o=AJqy8_SygpJZ4RJkJpUwDD3nKxpB5YQ@mail.gmail.com>
On 29/03/17 10:59, Brendan Higgins wrote:
> The main reason I took this approach is just because I thought it was
> cleaner from the perspective of the busses which are totally
> independent (except for the fact that they share a single hardware
> interrupt).
>
> I did not make any measurements, so I doubt that I have anything to
> add that you don't already know. I saw other usages of chained
> interrupts that do the same thing (scan a "status" register and use
> them to make software interrupts) and I thought that is basically what
> the dummy irq chip code is for. The only thing I thought I was doing
> that was novel was actually breaking out the dummy irqchip into its
> own driver; it is not my idea, but I do think makes it a lot cleaner.
> Nevertheless, it should be cheap in terms of number of instructions;
> the most expensive part looks like looking up the mapping. In any
> case, I think the low hanging fruit here is supporting buffering or
> DMA, like Ben suggested.
>
> To address the comment on being over engineered: outside of the init
> function (which would exist regardless of how we do this, if not here
> then in the I2C driver); the code is actually pretty small and
> generic.
>
> All that being said, it would not be very hard to do this without
> using the dummy irqchip code and it would definitely be smaller in
> terms of indirection and space used, but I think the code would
> actually be more complicated to read. We would be going back to having
> an I2C controller along with the I2C busses; where all the I2C
> controller does is read the IRQ register and then call the appropriate
> bus irq handler, which looks a lot like a dummy irqchip.
As long as you're happy with the performance and the restrictions that
come attached to the HW, I'm happy to take the irqchip patches.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* Re: [PATCH v2 2/2] phy: meson: add USB2 PHY support for Meson GXL and GXM
From: Kishon Vijay Abraham I @ 2017-03-29 10:56 UTC (permalink / raw)
To: Martin Blumenstingl,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
hendrik-MJglGmTD+GWCT0AhDRffsw, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
carlo-KA+7E9HrN00dnm+yROfE0A, khilman-rdvid1DuHRBWk0Htik3J/w
In-Reply-To: <CAFBinCCBkdADVX_9g54Lz2K3oPux2TnjPuotf1pz0mu6h6phTA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi,
On Wednesday 29 March 2017 03:03 AM, Martin Blumenstingl wrote:
> Hi Kishon,
>
> On Sat, Mar 18, 2017 at 2:00 PM, Martin Blumenstingl
> <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
>> This adds a new driver for the USB2 PHYs found on Meson GXL and GXM SoCs
>> (both SoCs are using the same USB PHY register layout).
>>
>> The USB2 PHY is a simple PHY which only has a few registers to configure
>> the mode (host/device) and a reset register (to enable/disable the PHY).
>>
>> Unfortunately there are no datasheets available for this PHY. The driver
>> was written by reading the code from Amlogic's GPL kernel sources and
>> by analyzing the registers on an actual GXL and GXM device running the
>> kernel that was shipped on the boards I have.
> gentle ping - did you have time to review this patch in v2 yet?
Have a few comments, see below..
>
>> Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>> ---
>> drivers/phy/Kconfig | 14 ++
>> drivers/phy/Makefile | 1 +
>> drivers/phy/phy-meson-gxl-usb2.c | 273 +++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 288 insertions(+)
>> create mode 100644 drivers/phy/phy-meson-gxl-usb2.c
>>
>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index dc5277ad1b5a..2573e139fd17 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -510,6 +510,19 @@ config PHY_MESON8B_USB2
>> and GXBB SoCs.
>> If unsure, say N.
>>
>> +config PHY_MESON_GXL_USB
>> + tristate "Meson GXL and GXM USB2 PHY drivers"
>> + default ARCH_MESON
>> + depends on OF && (ARCH_MESON || COMPILE_TEST)
>> + depends on USB_SUPPORT
>> + select USB_COMMON
>> + select GENERIC_PHY
>> + select REGMAP_MMIO
>> + help
>> + Enable this to support the Meson USB2 PHYs found in Meson
>> + GXL and GXM SoCs.
>> + If unsure, say N.
>> +
>> config PHY_NSP_USB3
>> tristate "Broadcom NorthStar plus USB3 PHY driver"
>> depends on OF && (ARCH_BCM_NSP || COMPILE_TEST)
>> @@ -518,4 +531,5 @@ config PHY_NSP_USB3
>> help
>> Enable this to support the Broadcom Northstar plus USB3 PHY.
>> If unsure, say N.
>> +
spurious space..
>> endmenu
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index e7b0feb1e125..e680b856e38e 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -62,4 +62,5 @@ obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
>> obj-$(CONFIG_ARCH_TEGRA) += tegra/
>> obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
>> obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
>> +obj-$(CONFIG_PHY_MESON_GXL_USB) += phy-meson-gxl-usb2.o
>> obj-$(CONFIG_PHY_NSP_USB3) += phy-bcm-nsp-usb3.o
>> diff --git a/drivers/phy/phy-meson-gxl-usb2.c b/drivers/phy/phy-meson-gxl-usb2.c
>> new file mode 100644
>> index 000000000000..4bf646a52c45
>> --- /dev/null
>> +++ b/drivers/phy/phy-meson-gxl-usb2.c
>> @@ -0,0 +1,273 @@
>> +/*
>> + * Meson GXL and GXM USB2 PHY driver
>> + *
>> + * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@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 version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/usb/of.h>
>> +
>> +/* bits [31:27] are read-only */
>> +#define U2P_R0 0x0
>> + #define U2P_R0_BYPASS_SEL BIT(0)
>> + #define U2P_R0_BYPASS_DM_EN BIT(1)
>> + #define U2P_R0_BYPASS_DP_EN BIT(2)
>> + #define U2P_R0_TXBITSTUFF_ENH BIT(3)
>> + #define U2P_R0_TXBITSTUFF_EN BIT(4)
>> + #define U2P_R0_DM_PULLDOWN BIT(5)
>> + #define U2P_R0_DP_PULLDOWN BIT(6)
>> + #define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7)
>> + #define U2P_R0_DP_VBUS_VLD_EXT BIT(8)
>> + #define U2P_R0_ADP_PRB_EN BIT(9)
>> + #define U2P_R0_ADP_DISCHARGE BIT(10)
>> + #define U2P_R0_ADP_CHARGE BIT(11)
>> + #define U2P_R0_DRV_VBUS BIT(12)
>> + #define U2P_R0_ID_PULLUP BIT(13)
>> + #define U2P_R0_LOOPBACK_EN_B BIT(14)
>> + #define U2P_R0_OTG_DISABLE BIT(15)
>> + #define U2P_R0_COMMON_ONN BIT(16)
>> + #define U2P_R0_FSEL_MASK GENMASK(19, 17)
>> + #define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20)
>> + #define U2P_R0_POWER_ON_RESET BIT(22)
>> + #define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23)
>> + #define U2P_R0_ID_SET_ID_DQ BIT(25)
>> + #define U2P_R0_ATE_RESET BIT(26)
>> + #define U2P_R0_FSV_MINUS BIT(27)
>> + #define U2P_R0_FSV_PLUS BIT(28)
>> + #define U2P_R0_BYPASS_DM_DATA BIT(29)
>> + #define U2P_R0_BYPASS_DP_DATA BIT(30)
>> +
>> +#define U2P_R1 0x4
>> + #define U2P_R1_BURN_IN_TEST BIT(0)
>> + #define U2P_R1_ACA_ENABLE BIT(1)
>> + #define U2P_R1_DCD_ENABLE BIT(2)
>> + #define U2P_R1_VDAT_SRC_EN_B BIT(3)
>> + #define U2P_R1_VDAT_DET_EN_B BIT(4)
>> + #define U2P_R1_CHARGES_SEL BIT(5)
>> + #define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6)
>> + #define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7)
>> + #define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9)
>> + #define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11)
>> + #define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13)
>> + #define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17)
>> + #define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21)
>> + #define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23)
>> + #define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26)
>> + #define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29)
>> +
>> +/* bits [31:14] are read-only */
>> +#define U2P_R2 0x8
>> + #define U2P_R2_DATA_IN_MASK GENMASK(3, 0)
>> + #define U2P_R2_DATA_IN_EN_MASK GENMASK(7, 4)
>> + #define U2P_R2_ADDR_MASK GENMASK(11, 8)
>> + #define U2P_R2_DATA_OUT_SEL BIT(12)
>> + #define U2P_R2_CLK BIT(13)
>> + #define U2P_R2_DATA_OUT_MASK GENMASK(17, 14)
>> + #define U2P_R2_ACA_PIN_RANGE_C BIT(18)
>> + #define U2P_R2_ACA_PIN_RANGE_B BIT(19)
>> + #define U2P_R2_ACA_PIN_RANGE_A BIT(20)
>> + #define U2P_R2_ACA_PIN_GND BIT(21)
>> + #define U2P_R2_ACA_PIN_FLOAT BIT(22)
>> + #define U2P_R2_CHARGE_DETECT BIT(23)
>> + #define U2P_R2_DEVICE_SESSION_VALID BIT(24)
>> + #define U2P_R2_ADP_PROBE BIT(25)
>> + #define U2P_R2_ADP_SENSE BIT(26)
>> + #define U2P_R2_SESSION_END BIT(27)
>> + #define U2P_R2_VBUS_VALID BIT(28)
>> + #define U2P_R2_B_VALID BIT(29)
>> + #define U2P_R2_A_VALID BIT(30)
>> + #define U2P_R2_ID_DIG BIT(31)
>> +
>> +#define U2P_R3 0xc
>> +
>> +#define RESET_COMPLETE_TIME 500
>> +
>> +struct phy_meson_gxl_usb2_priv {
>> + struct regmap *regmap;
>> + enum phy_mode mode;
>> + int is_enabled;
>> +};
>> +
>> +static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
>> + .reg_bits = 8,
>> + .val_bits = 32,
>> + .reg_stride = 4,
>> + .max_register = U2P_R3,
>> +};
>> +
>> +static int phy_meson_gxl_usb2_reset(struct phy *phy)
>> +{
>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> +
>> + if (priv->is_enabled) {
>> + /* reset the PHY and wait until settings are stabilized */
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>> + U2P_R0_POWER_ON_RESET);
>> + udelay(RESET_COMPLETE_TIME);
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>> + 0);
>> + udelay(RESET_COMPLETE_TIME);
>> + }
Instead of having big if condition blocks, it could be
if (!priv->is_enabled)
return 0
the configuration when priv->is_enabled is true should go here.
>> +
>> + return 0;
>> +}
>> +
>> +static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode)
>> +{
>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> +
>> + switch (mode) {
>> + case PHY_MODE_USB_HOST:
>> + case PHY_MODE_USB_OTG:
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
>> + U2P_R0_DM_PULLDOWN);
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
>> + U2P_R0_DP_PULLDOWN);
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0);
>> + break;
>> +
>> + case PHY_MODE_USB_DEVICE:
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
>> + 0);
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
>> + 0);
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
>> + U2P_R0_ID_PULLUP);
>> + break;
>> +
>> + default:
>> + return -EINVAL;
>> + }
>> +
>> + phy_meson_gxl_usb2_reset(phy);
>> +
>> + priv->mode = mode;
>> +
>> + return 0;
>> +}
>> +
>> +static int phy_meson_gxl_usb2_power_off(struct phy *phy)
>> +{
>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> +
>> + priv->is_enabled = 0;
>> +
>> + /* power off the PHY by putting it into reset mode */
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>> + U2P_R0_POWER_ON_RESET);
>> +
>> + return 0;
>> +}
>> +
>> +static int phy_meson_gxl_usb2_power_on(struct phy *phy)
>> +{
>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> + int ret;
>> +
>> + priv->is_enabled = 1;
>> +
>> + /* power on the PHY by taking it out of reset mode */
>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
>> +
>> + ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode);
Since this is already part of phy_ops, the consumer of this phy will take care
of setting the mode right?
>> + if (ret) {
>> + phy_meson_gxl_usb2_power_off(phy);
This would mess up the reference count in phy_core, since this function is also
part of the phy_ops. The consumer should be responsible for powering off the phy.
Thanks
Kishon
--
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 v6 2/5] irqchip/aspeed-i2c-ic: Add I2C IRQ controller for Aspeed
From: Joel Stanley @ 2017-03-29 10:58 UTC (permalink / raw)
To: Brendan Higgins
Cc: Wolfram Sang, Rob Herring, Mark Rutland, Thomas Gleixner,
Jason Cooper, Marc Zyngier, vz, mouse, Cédric Le Goater,
linux-i2c, devicetree, Linux Kernel Mailing List,
OpenBMC Maillist, Benjamin Herrenschmidt
In-Reply-To: <20170328051226.21677-3-brendanhiggins@google.com>
On Tue, Mar 28, 2017 at 3:42 PM, Brendan Higgins
<brendanhiggins@google.com> wrote:
> +static int __init aspeed_i2c_ic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + struct aspeed_i2c_ic *i2c_ic;
> +
> + i2c_ic = kzalloc(sizeof(*i2c_ic), GFP_KERNEL);
> + if (!i2c_ic)
> + return -ENOMEM;
> +
> + i2c_ic->base = of_iomap(node, 0);
> + if (IS_ERR(i2c_ic->base))
> + return PTR_ERR(i2c_ic->base);
> +
> + i2c_ic->parent_irq = irq_of_parse_and_map(node, 0);
> + if (i2c_ic->parent_irq < 0)
> + return i2c_ic->parent_irq;
> +
> + i2c_ic->irq_domain = irq_domain_add_linear(
> + node, ASPEED_I2C_IC_NUM_BUS,
> + &aspeed_i2c_ic_irq_domain_ops, NULL);
> + if (!i2c_ic->irq_domain)
> + return -ENOMEM;
> +
> + i2c_ic->irq_domain->name = "ast-i2c-domain";
Nit: Make this aspeed-i2c-domain to make this consistent with the
other Aspeed drivers in the kernel tree.
Could this irq code be embedded in the i2c driver? We took a similar
approach for the Aspeed GPIO driver, which has a similar IRQ structure
of one hardware IRQ that tells the driver to check status registers
for the precise irq source. The upside being all of the i2c code is in
the same place in the kernel tree.
Cheers,
Joel
^ permalink raw reply
* [PATCH v3 0/2] Tango PCIe controller support
From: Marc Gonzalez @ 2017-03-29 11:11 UTC (permalink / raw)
To: Bjorn Helgaas, Marc Zyngier, Thomas Gleixner
Cc: DT, Lorenzo Pieralisi, Mason, linux-pci, Thibaud Cornic,
Liviu Dudau, LKML, David Laight, Phuong Nguyen, Robin Murphy,
Linux ARM
Hello,
The patch is split in two parts, to ease review of two orthogonal
parts (MSI controller vs host bridge)
Marc Gonzalez (2):
PCI: Add tango MSI controller support
PCI: Add tango PCIe host bridge support
Documentation/devicetree/bindings/pci/tango-pcie.txt | 34 ++++
drivers/pci/host/Kconfig | 7 +
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pcie-tango.c | 344 +++++++++++++++++++++++++++++++++++++++
4 files changed, 386 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/tango-pcie.txt
create mode 100644 drivers/pci/host/pcie-tango.c
--
2.11.0
^ permalink raw reply
* Re: [PATCH 0/4] ARM: exynos: Fix Odroid U3 USB/LAN when TFTP booting (power sequence)
From: Hans Verkuil @ 2017-03-29 11:12 UTC (permalink / raw)
To: Krzysztof Kozlowski, Kukjin Kim, Javier Martinez Canillas,
Anand Moon, devicetree, linux-arm-kernel, linux-samsung-soc,
linux-kernel
Cc: Peter Chen, ulf.hansson, linux-pm, gregkh, linux-usb, sre,
robh+dt, Markus Reichl, broonie, stern, Sylwester Nawrocki,
Marek Szyprowski
In-Reply-To: <20170107085203.4431-1-krzk@kernel.org>
Hi Krzysztof,
On 07/01/17 09:51, Krzysztof Kozlowski wrote:
> Hi,
>
> Thanks to Markus Reichl, I got an Odroid U3 to work with. Thanks to Peter
> Chen, we got a power sequence generic library which solves my long
> standing Odroid U3 problem - no LAN9730 if it was enabled by bootloader.
>
> My previous attempts for this can be found here [0].
>
> This patchset is based on Peter's v11 of power sequence [1].
> Patchset is available also on my Github [2].
>
> More detailed analysis is described in patch 2/4 ("ARM: dts: exynos: Fix
> LAN9730 on Odroid U3 after tftpboot").
It's rather late, but I finally had a chance to test this and it works.
So:
Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
This was with u-boot version v2016.09.01 and kernel 4.11.0-rc1.
Regards,
Hans
>
>
> Best regards,
> Krzysztof
>
>
> [0] http://www.spinics.net/lists/linux-mmc/msg37386.html
> [1] https://lwn.net/Articles/710736/
> [2] https://github.com/krzk/linux/commits/for-next/odroid-u3-usb3503-pwrseq
>
> Krzysztof Kozlowski (4):
> ARM: dts: exynos: Fix indentation of EHCI and OHCI ports
> ARM: dts: exynos: Fix LAN9730 on Odroid U3 after tftpboot
> ARM: exynos_defconfig: Enable power sequence for Odroid U3
> ARM: multi_v7_defconfig: Enable power sequence for Odroid U3
>
> arch/arm/boot/dts/exynos4.dtsi | 24 ++++++++++++------------
> arch/arm/boot/dts/exynos4412-odroidu3.dts | 21 +++++++++++++++++++++
> arch/arm/configs/exynos_defconfig | 2 ++
> arch/arm/configs/multi_v7_defconfig | 1 +
> 4 files changed, 36 insertions(+), 12 deletions(-)
>
^ permalink raw reply
* Re: [PATCH v2 6/8] bus: brcmstb_gisb: Add ARM64 support
From: Mark Rutland @ 2017-03-29 11:20 UTC (permalink / raw)
To: Doug Berger
Cc: wangkefeng.wang, catalin.marinas, linus.walleij, will.deacon,
mingo, f.fainelli, jonathanh, bgolaszewski,
bcm-kernel-feedback-list, shijie.huang, treding, devicetree,
suzuki.poulose, robh+dt, gregory.0xf0, sandeepa.s.prabhu,
linux-arm-kernel, mirza.krak, linux-kernel, james.morse, olof,
computersforpeace
In-Reply-To: <20170328213431.10904-7-opendmb@gmail.com>
Hi,
On Tue, Mar 28, 2017 at 02:34:29PM -0700, Doug Berger wrote:
> From: Florian Fainelli <f.fainelli@gmail.com>
>
> Hook to the ARM64 data abort exception #16: synchronous external
> abort, which is how the GISB errors will be funneled back to the
> ARM64 CPU in case of problems
I believe that you can use a die notifier for this, and that you don't
need to hook the low-level architectural fault here.
I note that the code doesn't even look at the faulting address, and
likely doesn't have the information to do anything with it, so it make
no sense to me for this code to hook the low-level fault.
Further, as an aside, from digging into how we handle unexpected faults
it appears that we don't always treat some faults (e.g. TLB conflict,
faults on PTW) sufficiently fatally when they occur at EL0, so we likely
need to do so rework there.
Thanks,
Mark.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/bus/Kconfig | 2 +-
> drivers/bus/brcmstb_gisb.c | 15 ++++++++++++---
> 2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
> index 0a52da439abf..d2a5f1184022 100644
> --- a/drivers/bus/Kconfig
> +++ b/drivers/bus/Kconfig
> @@ -57,7 +57,7 @@ config ARM_CCN
>
> config BRCMSTB_GISB_ARB
> bool "Broadcom STB GISB bus arbiter"
> - depends on ARM || MIPS
> + depends on ARM || ARM64 || MIPS
> default ARCH_BRCMSTB || BMIPS_GENERIC
> help
> Driver for the Broadcom Set Top Box System-on-a-chip internal bus
> diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
> index edf79432f899..500b6bb5c739 100644
> --- a/drivers/bus/brcmstb_gisb.c
> +++ b/drivers/bus/brcmstb_gisb.c
> @@ -30,6 +30,11 @@
> #include <asm/signal.h>
> #endif
>
> +#ifdef CONFIG_ARM64
> +#include <asm/signal.h>
> +#include <asm/system_misc.h>
> +#endif
> +
> #ifdef CONFIG_MIPS
> #include <asm/traps.h>
> #endif
> @@ -225,7 +230,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
> return 0;
> }
>
> -#ifdef CONFIG_ARM
> +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
> static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
> struct pt_regs *regs)
> {
> @@ -235,7 +240,7 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
> list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
> brcmstb_gisb_arb_decode_addr(gdev, "bus error");
>
> -#if !defined(CONFIG_ARM_LPAE)
> +#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
> /*
> * If it was an imprecise abort, then we need to correct the
> * return address to be _after_ the instruction.
> @@ -247,7 +252,7 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
> /* Always report unhandled exception */
> return 1;
> }
> -#endif
> +#endif /* CONFIG_ARM || CONFIG_ARM64 */
>
> #ifdef CONFIG_MIPS
> static int brcmstb_bus_error_handler(struct pt_regs *regs, int is_fixup)
> @@ -395,6 +400,10 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
> "imprecise external abort");
> #endif
> #endif /* CONFIG_ARM */
> +#ifdef CONFIG_ARM64
> + hook_fault_code(16, brcmstb_bus_error_handler, SIGBUS, 0,
> + "synchronous external abort");
> +#endif
> #ifdef CONFIG_MIPS
> board_be_handler = brcmstb_bus_error_handler;
> #endif
> --
> 2.12.0
>
^ permalink raw reply
* Re: [PATCH v2 2/7] dt-bindings: pinctrl: Add RZ/A1 bindings doc
From: Geert Uytterhoeven @ 2017-03-29 11:20 UTC (permalink / raw)
To: Linus Walleij
Cc: jacopo, Jacopo Mondi, Geert Uytterhoeven, Laurent Pinchart,
Chris Brandt, Rob Herring, Mark Rutland, Russell King,
Linux-Renesas, linux-gpio@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CACRpkdbT3091MzAQ_hO5Hc9=gQz-eDNCDtEnVG-3G+jJ+eO+Fw@mail.gmail.com>
Hi Linus,
On Wed, Mar 29, 2017 at 12:15 PM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> On Wed, Mar 29, 2017 at 9:35 AM, Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
>>> See for example:
>>> include/dt-bindings/pinctrl/mt65xx.h
>>>
>>> And how that is used in:
>>> arch/arm/boot/dts/mt2701-pinfunc.h
>>> arch/arm/boot/dts/mt2701-evb.dts
>>>
>>> The docs are here:
>>> Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
>>
>> All of the above pack the information for a pin into a single 32-bit integer.
>> Is that what you want us to use, too?
>> Currently we use two integers: 1) pin index, and 2) function/flags combo.
>
> I don't really know what you need, sorry. But some kind of figure, yes.
> I would say whatever makes sense. 16+16 bits makes sense in most
> combinatorial spaces does it not? If you split 32 bits in 16 bits for
> pin and 16 bits for function, do you have more than 2^16 pins or 2^16
> functions?
>
> If you really do we may need to go for u64 but ... really? Is there
> a rational reason for that other than "we did it like this first"?
>
> I do not understand the notion of "flags" here. I hope that is not referring
Flags refers to BI_DIR, SWIO_IN, and SWIO_OUT, from
https://patchwork.kernel.org/patch/9643047/
32-bit should be enough to cover pins, function, and flags.
> to pin config, because I expect that to use the standard pin config
> bindings outside of the pinmux value which should just define the
> pin+function combo:
>
> node {
> pinmux = <PIN_NUMBER_PINMUX>;
> GENERIC_PINCONFIG;
> };
>
> Example from Mediatek:
>
> i2c1_pins_a: i2c1@0 {
> pins {
> pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
> <MT8135_PIN_196_SCL1__FUNC_SCL1>;
If we follow this example, then we can list all combinations in
include/dt-bindings/pinctrl/r7s72100-pinctrl.h, instead of creating the value
by combining the bits using a macro where we need it in the DTS.
It's gonna be a long list, though...
> bias-pull-up = <55>;
> };
> };
>
> So this allows for a combine pin+function number but pull ups,
> bias etc are not baked into the thing, they have to be added on
> separately with the generic bindings, which is nice and very readable.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v2] clk/axs10x: introduce AXS10X pll driver
From: Vlad Zakharov @ 2017-03-29 11:20 UTC (permalink / raw)
To: sboyd@codeaurora.org, mturquette@baylibre.com,
Vladislav.Zakharov@synopsys.com
Cc: Jose.Abreu@synopsys.com, robh@kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
mark.rutland@arm.com, linux-snps-arc@lists.infradead.org,
linux-clk@vger.kernel.org
In-Reply-To: <20170303235005.GV25384@codeaurora.org>
Hi Stephen, Michael,
On Fri, 2017-03-03 at 15:50 -0800, Stephen Boyd wrote:
> On 03/03, Vlad Zakharov wrote:
> >
> > Hi Michael, Stephen,
> >
> > On Tue, 2017-02-21 at 16:11 +0300, Vlad Zakharov wrote:
> > >
> > > AXS10X boards manages it's clocks using various PLLs. These PLL has same
> > > dividers and corresponding control registers mapped to different addresses.
> > > So we add one common driver for such PLLs.
> > >
> > > Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and
> > > ODIV. Output clock value is managed using these dividers.
> > >
> > > We add pre-defined tables with supported rate values and appropriate
> > > configurations of IDIV, FBDIV and ODIV for each value.
> > >
> > > As of today we add support for PLLs that generate clock for the
> > > following devices:
> > > * ARC core on AXC CPU tiles.
> > > * ARC PGU on ARC SDP Mainboard.
> > > and more to come later.
> > >
> > > Acked-by: Rob Herring <robh@kernel.org>
> > > Signed-off-by: Vlad Zakharov <vzakhar@synopsys.com>
> > > Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> > > Cc: Michael Turquette <mturquette@baylibre.com>
> > > Cc: Stephen Boyd <sboyd@codeaurora.org>
> > > Cc: Mark Rutland <mark.rutland@arm.com>
> >
> > Maybe you have any comments or remarks about this patch? And if you don't could you please apply it.
> >
>
> I haven't reviewed it yet. The merge window is upon us right now
> so I'll probably get to going through the queue this weekend/next
> week.
>
Please treat this message as a polite reminder to review my patch.
It is required for some subsystems on our boards, e.g. for ARC PGU.
Thanks.
--
Best regards,
Vlad Zakharov <vzakhar@synopsys.com>
_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc
^ permalink raw reply
* Re: [PATCH v2 2/8] arm64: mm: mark fault_info __ro_after_init
From: Mark Rutland @ 2017-03-29 11:23 UTC (permalink / raw)
To: Doug Berger
Cc: wangkefeng.wang, catalin.marinas, linus.walleij, will.deacon,
mingo, f.fainelli, jonathanh, bgolaszewski,
bcm-kernel-feedback-list, shijie.huang, treding, devicetree,
suzuki.poulose, robh+dt, gregory.0xf0, sandeepa.s.prabhu,
linux-arm-kernel, mirza.krak, linux-kernel, james.morse, olof,
computersforpeace
In-Reply-To: <20170328213431.10904-3-opendmb@gmail.com>
On Tue, Mar 28, 2017 at 02:34:25PM -0700, Doug Berger wrote:
> The fault_info table must be made writeable to allow installation
> of custom memory abort handlers, but it can be made read-only
> after initialization to provide some protection.
>
> Signed-off-by: Doug Berger <opendmb@gmail.com>
Thanks for putting this together. I agree that making this RO is good.
However, I also think that we should not allow arbitrary hooking of
fault codes, and thus this can be const.
Thanks,
Mark.
> ---
> arch/arm64/mm/fault.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index cdf1260f1005..43319ed58a47 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -493,7 +493,7 @@ static struct fault_info {
> int sig;
> int code;
> const char *name;
> -} fault_info[] = {
> +} fault_info[] __ro_after_init = {
> { do_bad, SIGBUS, 0, "ttbr address size fault" },
> { do_bad, SIGBUS, 0, "level 1 address size fault" },
> { do_bad, SIGBUS, 0, "level 2 address size fault" },
> --
> 2.12.0
>
^ permalink raw reply
* Re: [PATCH v2 8/8] bus: brcmstb_gisb: update to support new revision
From: Mark Rutland @ 2017-03-29 11:25 UTC (permalink / raw)
To: Doug Berger
Cc: robh+dt, catalin.marinas, will.deacon, computersforpeace,
gregory.0xf0, f.fainelli, bcm-kernel-feedback-list,
wangkefeng.wang, james.morse, mingo, sandeepa.s.prabhu,
shijie.huang, linus.walleij, treding, jonathanh, olof, mirza.krak,
suzuki.poulose, bgolaszewski, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20170328213431.10904-9-opendmb@gmail.com>
On Tue, Mar 28, 2017 at 02:34:31PM -0700, Doug Berger wrote:
> The 7278 introduces a new version of this core. This
> commit adds support for that revision.
>
> Signed-off-by: Doug Berger <opendmb@gmail.com>
> ---
> Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt | 3 ++-
> drivers/bus/brcmstb_gisb.c | 10 ++++++++++
> 2 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
> index 1eceefb20f01..8a6c3c2e58fe 100644
> --- a/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
> +++ b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
> @@ -3,7 +3,8 @@ Broadcom GISB bus Arbiter controller
> Required properties:
>
> - compatible:
> - "brcm,gisb-arb" or "brcm,bcm7445-gisb-arb" for 28nm chips
> + "brcm,bcm7278-gisb-arb" for V7 28nm chips
> + "brcm,gisb-arb" or "brcm,bcm7445-gisb-arb" for other 28nm chips
> "brcm,bcm7435-gisb-arb" for newer 40nm chips
> "brcm,bcm7400-gisb-arb" for older 40nm chips and all 65nm chips
> "brcm,bcm7038-gisb-arb" for 130nm chips
For the binding:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Thanks,
Mark.
^ permalink raw reply
* [PATCH v3 1/2] PCI: Add tango MSI controller support
From: Marc Gonzalez @ 2017-03-29 11:29 UTC (permalink / raw)
To: Bjorn Helgaas, Marc Zyngier, Thomas Gleixner
Cc: DT, Lorenzo Pieralisi, Mason, linux-pci, Thibaud Cornic,
Liviu Dudau, LKML, David Laight, Phuong Nguyen, Robin Murphy,
Linux ARM
In-Reply-To: <5309e718-5813-5b79-db57-9d702b50d0f9@sigmadesigns.com>
The MSI controller in Tango supports 256 message-signaled interrupts,
and a single doorbell address.
Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
---
Changes since v0.2
- Support 256 MSIs instead of only 32
- Use spinlock_t instead of struct mutex
- Add MSI_FLAG_PCI_MSIX flag
IRQs are acked in tango_msi_isr because handle_simple_irq leaves
ack, clear, mask and unmask up to the driver. For the same reason,
interrupt enable mask is updated from tango_irq_domain_alloc/free.
---
drivers/pci/host/pcie-tango.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 194 insertions(+)
diff --git a/drivers/pci/host/pcie-tango.c b/drivers/pci/host/pcie-tango.c
new file mode 100644
index 000000000000..e88850983a1d
--- /dev/null
+++ b/drivers/pci/host/pcie-tango.c
@@ -0,0 +1,194 @@
+#include <linux/module.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/pci-ecam.h>
+#include <linux/msi.h>
+
+#define MSI_MAX 256
+
+struct tango_pcie {
+ DECLARE_BITMAP(bitmap, MSI_MAX);
+ spinlock_t lock;
+ void __iomem *mux;
+ void __iomem *msi_status;
+ void __iomem *msi_mask;
+ phys_addr_t msi_doorbell;
+ struct irq_domain *irq_domain;
+ struct irq_domain *msi_domain;
+ int irq;
+};
+
+/*** MSI CONTROLLER SUPPORT ***/
+
+static void dispatch(struct tango_pcie *pcie, unsigned long status, int base)
+{
+ unsigned int pos, virq;
+
+ for_each_set_bit(pos, &status, 32) {
+ virq = irq_find_mapping(pcie->irq_domain, base + pos);
+ generic_handle_irq(virq);
+ }
+}
+
+static void tango_msi_isr(struct irq_desc *desc)
+{
+ u32 status;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct tango_pcie *pcie = irq_desc_get_handler_data(desc);
+ unsigned int base, offset, pos = 0;
+
+ chained_irq_enter(chip, desc);
+
+ while ((pos = find_next_bit(pcie->bitmap, MSI_MAX, pos)) < MSI_MAX) {
+ base = round_down(pos, 32);
+ offset = (pos / 32) * 4;
+ status = readl_relaxed(pcie->msi_status + offset);
+ writel_relaxed(status, pcie->msi_status + offset);
+ dispatch(pcie, status, base);
+ pos = base + 32;
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip tango_msi_irq_chip = {
+ .name = "MSI",
+ .irq_mask = pci_msi_mask_irq,
+ .irq_unmask = pci_msi_unmask_irq,
+};
+
+#define USE_DEF_OPS (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS)
+
+static struct msi_domain_info msi_domain_info = {
+ .flags = USE_DEF_OPS | MSI_FLAG_PCI_MSIX,
+ .chip = &tango_msi_irq_chip,
+};
+
+static void tango_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+ struct tango_pcie *pcie = irq_data_get_irq_chip_data(data);
+
+ msg->address_lo = lower_32_bits(pcie->msi_doorbell);
+ msg->address_hi = upper_32_bits(pcie->msi_doorbell);
+ msg->data = data->hwirq;
+}
+
+static int tango_set_affinity(struct irq_data *irq_data,
+ const struct cpumask *mask, bool force)
+{
+ return -EINVAL;
+}
+
+static struct irq_chip tango_msi_chip = {
+ .name = "MSI",
+ .irq_compose_msi_msg = tango_compose_msi_msg,
+ .irq_set_affinity = tango_set_affinity,
+};
+
+static int find_free_msi(struct irq_domain *dom, unsigned int virq)
+{
+ u32 val;
+ struct tango_pcie *pcie = dom->host_data;
+ unsigned int offset, pos;
+
+ pos = find_first_zero_bit(pcie->bitmap, MSI_MAX);
+ if (pos >= MSI_MAX)
+ return -ENOSPC;
+
+ offset = (pos / 32) * 4;
+ val = readl_relaxed(pcie->msi_mask + offset);
+ writel_relaxed(val | BIT(pos % 32), pcie->msi_mask + offset);
+ __set_bit(pos, pcie->bitmap);
+
+ irq_domain_set_info(dom, virq, pos, &tango_msi_chip,
+ dom->host_data, handle_simple_irq, NULL, NULL);
+
+ return 0;
+}
+
+static int tango_irq_domain_alloc(struct irq_domain *dom,
+ unsigned int virq, unsigned int nr_irqs, void *args)
+{
+ int err;
+ struct tango_pcie *pcie = dom->host_data;
+
+ spin_lock(&pcie->lock);
+ err = find_free_msi(dom, virq);
+ spin_unlock(&pcie->lock);
+
+ return err;
+}
+
+static void tango_irq_domain_free(struct irq_domain *dom,
+ unsigned int virq, unsigned int nr_irqs)
+{
+ u32 val;
+ struct irq_data *d = irq_domain_get_irq_data(dom, virq);
+ struct tango_pcie *pcie = irq_data_get_irq_chip_data(d);
+ unsigned int offset, pos = d->hwirq;
+
+ spin_lock(&pcie->lock);
+
+ offset = (pos / 32) * 4;
+ val = readl_relaxed(pcie->msi_mask + offset);
+ writel_relaxed(val & ~BIT(pos % 32), pcie->msi_mask + offset);
+ __clear_bit(pos, pcie->bitmap);
+
+ spin_unlock(&pcie->lock);
+}
+
+static const struct irq_domain_ops msi_dom_ops = {
+ .alloc = tango_irq_domain_alloc,
+ .free = tango_irq_domain_free,
+};
+
+static int tango_msi_remove(struct platform_device *pdev)
+{
+ struct tango_pcie *msi = platform_get_drvdata(pdev);
+
+ irq_set_chained_handler_and_data(msi->irq, NULL, NULL);
+ irq_domain_remove(msi->msi_domain);
+ irq_domain_remove(msi->irq_domain);
+
+ return 0;
+}
+
+static int tango_msi_probe(struct platform_device *pdev, struct tango_pcie *pcie)
+{
+ int i, virq;
+ struct fwnode_handle *fwnode = of_node_to_fwnode(pdev->dev.of_node);
+ struct irq_domain *msi_dom, *irq_dom;
+
+ spin_lock_init(&pcie->lock);
+
+ for (i = 0; i < MSI_MAX / 32; ++i)
+ writel_relaxed(0, pcie->msi_mask + i * 4);
+
+ irq_dom = irq_domain_create_linear(fwnode, MSI_MAX, &msi_dom_ops, pcie);
+ if (!irq_dom) {
+ pr_err("Failed to create IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ msi_dom = pci_msi_create_irq_domain(fwnode, &msi_domain_info, irq_dom);
+ if (!msi_dom) {
+ pr_err("Failed to create MSI domain\n");
+ irq_domain_remove(irq_dom);
+ return -ENOMEM;
+ }
+
+ virq = platform_get_irq(pdev, 1);
+ if (virq <= 0) {
+ pr_err("Failed to map IRQ\n");
+ irq_domain_remove(msi_dom);
+ irq_domain_remove(irq_dom);
+ return -ENXIO;
+ }
+
+ pcie->irq_domain = irq_dom;
+ pcie->msi_domain = msi_dom;
+ pcie->irq = virq;
+ irq_set_chained_handler_and_data(virq, tango_msi_isr, pcie);
+
+ return 0;
+}
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2 1/8] arm64: mm: Allow installation of memory abort handlers
From: Mark Rutland @ 2017-03-29 11:32 UTC (permalink / raw)
To: Doug Berger, catalin.marinas, will.deacon
Cc: robh+dt, computersforpeace, gregory.0xf0, f.fainelli,
bcm-kernel-feedback-list, wangkefeng.wang, james.morse, mingo,
sandeepa.s.prabhu, shijie.huang, linus.walleij, treding,
jonathanh, olof, mirza.krak, suzuki.poulose, bgolaszewski,
devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <20170328213431.10904-2-opendmb@gmail.com>
Hi,
On Tue, Mar 28, 2017 at 02:34:24PM -0700, Doug Berger wrote:
> From: Florian Fainelli <f.fainelli@gmail.com>
>
> Similarly to what the ARM/Linux kernel provides, add a hook_fault_code()
> function which allows drivers or other parts of the kernel to install
> custom memory abort handlers. This is useful when a given SoC's busing
> does not propagate the exact faulting physical address, but there is a
> way to read it through e.g: a special arbiter driver.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Personally, I do not think that it makes sense to allow arbitrary code
to hook such low-level fault handling.
IMO, if it is truly necessary to allow drivers to handle particular
faults, that should be driven by data associated with the relevant
mapping (e.g. the VMA), rather than allowing code to hook *all* faults.
>From my PoV, NAK to this interface to take over low-level fault
handling.
Catalin and Will have the final say here, as the arm64 maintainers.
Thanks,
Mark.
> ---
> arch/arm64/include/asm/system_misc.h | 3 +++
> arch/arm64/mm/fault.c | 15 ++++++++++++++-
> 2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
> index bc812435bc76..e05f5b8c7c1c 100644
> --- a/arch/arm64/include/asm/system_misc.h
> +++ b/arch/arm64/include/asm/system_misc.h
> @@ -38,6 +38,9 @@ void arm64_notify_die(const char *str, struct pt_regs *regs,
> void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
> struct pt_regs *),
> int sig, int code, const char *name);
> +void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
> + struct pt_regs *),
> + int sig, int code, const char *name);
>
> struct mm_struct;
> extern void show_pte(struct mm_struct *mm, unsigned long addr);
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 4bf899fb451b..cdf1260f1005 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -488,7 +488,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
> return 1;
> }
>
> -static const struct fault_info {
> +static struct fault_info {
> int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
> int sig;
> int code;
> @@ -560,6 +560,19 @@ static const struct fault_info {
> { do_bad, SIGBUS, 0, "unknown 63" },
> };
>
> +void __init hook_fault_code(int nr,
> + int (*fn)(unsigned long, unsigned int, struct pt_regs *),
> + int sig, int code, const char *name)
> +{
> + BUG_ON(nr < 0 || nr >= ARRAY_SIZE(fault_info));
> +
> + fault_info[nr].fn = fn;
> + fault_info[nr].sig = sig;
> + fault_info[nr].code = code;
> + fault_info[nr].name = name;
> +}
> +
> +
> static const char *fault_name(unsigned int esr)
> {
> const struct fault_info *inf = fault_info + (esr & 63);
> --
> 2.12.0
>
^ permalink raw reply
* [PATCH v3 2/2] PCI: Add tango PCIe host bridge support
From: Marc Gonzalez @ 2017-03-29 11:34 UTC (permalink / raw)
To: Bjorn Helgaas, Marc Zyngier, Thomas Gleixner
Cc: DT, Lorenzo Pieralisi, Mason, linux-pci, Thibaud Cornic,
Liviu Dudau, LKML, David Laight, Phuong Nguyen, Robin Murphy,
Linux ARM
In-Reply-To: <5309e718-5813-5b79-db57-9d702b50d0f9@sigmadesigns.com>
This driver is used to work around HW bugs in the controller.
Note: the controller does NOT support the following features.
Legacy PCI interrupts
IO space
Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
---
Documentation/devicetree/bindings/pci/tango-pcie.txt | 33 +++++++++
drivers/pci/host/Kconfig | 7 ++
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pcie-tango.c | 150 +++++++++++++++++++++++++++++++++++++++
4 files changed, 191 insertions(+)
diff --git a/Documentation/devicetree/bindings/pci/tango-pcie.txt b/Documentation/devicetree/bindings/pci/tango-pcie.txt
new file mode 100644
index 000000000000..f8e150ec41d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/tango-pcie.txt
@@ -0,0 +1,33 @@
+Sigma Designs Tango PCIe controller
+
+Required properties:
+
+- compatible: "sigma,smp8759-pcie"
+- reg: address/size of PCI configuration space, and pcie_reg
+- bus-range: defined by size of PCI configuration space
+- device_type: "pci"
+- #size-cells: <2>
+- #address-cells: <3>
+- #interrupt-cells: <1>
+- ranges: translation from system to bus addresses
+- interrupts: spec for misc interrupts and MSI
+- msi-controller
+
+Example:
+
+ pcie@2e000 {
+ compatible = "sigma,smp8759-pcie";
+ reg = <0x50000000 SZ_64M>, <0x2e000 0x100>;
+ bus-range = <0 63>;
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ #interrupt-cells = <1>;
+ /* http://elinux.org/Device_Tree_Usage#PCI_Address_Translation */
+ /* BUS_ADDRESS(3) CPU_PHYSICAL(1) SIZE(2) */
+ ranges = <0x02000000 0x0 0x04000000 0x54000000 0x0 SZ_192M>;
+ interrupts =
+ <54 IRQ_TYPE_LEVEL_HIGH>, /* misc interrupts */
+ <55 IRQ_TYPE_LEVEL_HIGH>; /* MSI */
+ msi-controller;
+ };
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index d7e7c0a827c3..8a622578a760 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -285,6 +285,13 @@ config PCIE_ROCKCHIP
There is 1 internal PCIe port available to support GEN2 with
4 slots.
+config PCIE_TANGO
+ tristate "Tango PCIe controller"
+ depends on ARCH_TANGO && PCI_MSI && OF
+ select PCI_HOST_COMMON
+ help
+ Say Y here to enable PCIe controller support on Tango SoC.
+
config VMD
depends on PCI_MSI && X86_64
tristate "Intel Volume Management Device Driver"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 084cb4983645..fc7ea90196f3 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -32,4 +32,5 @@ obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
+obj-$(CONFIG_PCIE_TANGO) += pcie-tango.o
obj-$(CONFIG_VMD) += vmd.o
diff --git a/drivers/pci/host/pcie-tango.c b/drivers/pci/host/pcie-tango.c
index e88850983a1d..dbc2663486b5 100644
--- a/drivers/pci/host/pcie-tango.c
+++ b/drivers/pci/host/pcie-tango.c
@@ -192,3 +192,153 @@ static int tango_msi_probe(struct platform_device *pdev, struct tango_pcie *pcie
return 0;
}
+
+/*** HOST BRIDGE SUPPORT ***/
+
+static int smp8759_config_read(struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 *val)
+{
+ int ret;
+ struct pci_config_window *cfg = bus->sysdata;
+ struct tango_pcie *pcie = dev_get_drvdata(cfg->parent);
+
+ /*
+ * QUIRK #1
+ * Reads in configuration space outside devfn 0 return garbage.
+ */
+ if (devfn != 0) {
+ *val = ~0; /* Is this required even if we return an error? */
+ return PCIBIOS_FUNC_NOT_SUPPORTED; /* Error seems appropriate */
+ }
+
+ /*
+ * QUIRK #2
+ * The root complex advertizes a fake BAR, which is used to filter
+ * bus-to-system requests. Hide it from Linux.
+ */
+ if (where == PCI_BASE_ADDRESS_0 && bus->number == 0) {
+ *val = 0; /* 0 or ~0 to hide the BAR from Linux? */
+ return PCIBIOS_SUCCESSFUL; /* Should we return error or success? */
+ }
+
+ /*
+ * QUIRK #3
+ * Unfortunately, config and mem spaces are muxed.
+ * Linux does not support such a setting, since drivers are free
+ * to access mem space directly, at any time.
+ * Therefore, we can only PRAY that config and mem space accesses
+ * NEVER occur concurrently.
+ */
+ writel_relaxed(1, pcie->mux);
+ ret = pci_generic_config_read(bus, devfn, where, size, val);
+ writel_relaxed(0, pcie->mux);
+
+ return ret;
+}
+
+static int smp8759_config_write(struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 val)
+{
+ int ret;
+ struct pci_config_window *cfg = bus->sysdata;
+ struct tango_pcie *pcie = dev_get_drvdata(cfg->parent);
+
+ writel_relaxed(1, pcie->mux);
+ ret = pci_generic_config_write(bus, devfn, where, size, val);
+ writel_relaxed(0, pcie->mux);
+
+ return ret;
+}
+
+static struct pci_ecam_ops smp8759_ecam_ops = {
+ .bus_shift = 20,
+ .pci_ops = {
+ .map_bus = pci_ecam_map_bus,
+ .read = smp8759_config_read,
+ .write = smp8759_config_write,
+ }
+};
+
+static const struct of_device_id tango_pcie_ids[] = {
+ { .compatible = "sigma,smp8759-pcie" },
+ { /* sentinel */ },
+};
+
+static void smp8759_init(struct tango_pcie *pcie, void __iomem *base)
+{
+ pcie->mux = base + 0x48;
+ pcie->msi_status = base + 0x80;
+ pcie->msi_mask = base + 0xa0;
+ pcie->msi_doorbell = 0xa0000000 + 0x2e07c;
+}
+
+static int tango_pcie_probe(struct platform_device *pdev)
+{
+ int ret;
+ void __iomem *base;
+ struct resource *res;
+ struct tango_pcie *pcie;
+ struct device *dev = &pdev->dev;
+
+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pcie);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ if (of_device_is_compatible(dev->of_node, "sigma,smp8759-pcie"))
+ smp8759_init(pcie, base);
+
+ ret = tango_msi_probe(pdev, pcie);
+ if (ret)
+ return ret;
+
+ return pci_host_common_probe(pdev, &smp8759_ecam_ops);
+}
+
+static int tango_pcie_remove(struct platform_device *pdev)
+{
+ return tango_msi_remove(pdev);
+}
+
+static struct platform_driver tango_pcie_driver = {
+ .probe = tango_pcie_probe,
+ .remove = tango_pcie_remove,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = tango_pcie_ids,
+ },
+};
+
+module_platform_driver(tango_pcie_driver);
+
+#define VENDOR_SIGMA 0x1105
+
+/*
+ * QUIRK #4
+ * The root complex advertizes the wrong device class.
+ * Header Type 1 is for PCI-to-PCI bridges.
+ */
+static void tango_fixup_class(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(VENDOR_SIGMA, PCI_ANY_ID, tango_fixup_class);
+
+/*
+ * QUIRK #5
+ * Only transfers within the root complex BAR are forwarded to the host.
+ * By default, the DMA framework expects that
+ * PCI address 0x8000_0000 maps to system address 0x8000_0000
+ * which is where DRAM0 is mapped.
+ */
+static void tango_fixup_bar(struct pci_dev *dev)
+{
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x80000000);
+}
+DECLARE_PCI_FIXUP_FINAL(VENDOR_SIGMA, PCI_ANY_ID, tango_fixup_bar);
--
2.11.0
^ permalink raw reply related
* Re: [GIT PULL] PCI: Support for configurable PCI endpoint
From: Niklas Cassel @ 2017-03-29 11:42 UTC (permalink / raw)
To: Kishon Vijay Abraham I, Bjorn Helgaas, Joao Pinto, linux-pci,
linux-doc, linux-kernel, devicetree, linux-omap, linux-arm-kernel
Cc: hch, nsekhar
In-Reply-To: <20170327094520.3129-1-kishon@ti.com>
On 03/27/2017 11:44 AM, Kishon Vijay Abraham I wrote:
> Hi Bjorn,
>
> Please find the pull request for PCI endpoint support below. I've
> also included all the history here.
>
> Changes from v4:
> *) add #syscon-cells property and used of_parse_phandle_with_args
> to perform a configuration in syscon module (as suggested by
> Rob Herring)
> *) Remove unnecessary white space.
>
> Changes from v3:
> *) fixed a typo and adapted to https://lkml.org/lkml/2017/3/13/562.
>
> Changes from v2:
> *) changed the configfs structure as suggested by Christoph Hellwig. With
> this change the framework creates configfs entry for EP function driver
> and EP controller. Previously these entries have to be created by the
> the user. (Haven't changed the epc core or epf core except for invoking
> configfs APIs to create entries for EP function driver and EP controller.
> That's mostly because the EP function device can still be created by
> directly invoking the epf core API without using configfs).
> *) Now the user has to use configfs entry 'start' to start the link.
> This was previously done by the function driver. However in the case of
> multi function EP, the function driver shouldn't start the link.
>
> Changes from v1:
> *) The preparation patches for adding EP support is removed and is sent
> separately
> *) Added device ID for DRA74x/DRA72x and used it instead of
> using "PCI_ANY_ID"
> *) Added userguide for PCI endpoint test function
>
> Major Improvements from RFC:
> *) support multi-function devices (hw supported not virtual)
> *) Access host side buffers
> *) Raise MSI interrupts
> *) Add user space program to use the host side PCI driver
> *) Adapt all other users of designware to use the new design (only
> compile tested. Since I have only dra7xx boards, the new design
> has only been tested in dra7xx. I'd require the help of others
> to test the platforms they have access to).
>
> This series has been developed over 4.11-rc1 + [1]
> [1] -> https://lkml.org/lkml/2017/3/13/562
>
> Let me know if this has to be re-based to some of your branch.
>
> Thanks
> Kishon
>
> The following changes since commit 623e87fec8ab7867fb51b3079196bd10718a60ce:
>
> PCI: dwc: dra7xx: Push request_irq call to the bottom of probe (2017-03-22 20:35:30 +0530)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git tags/pci-endpoint-for-4.12
>
> for you to fetch changes up to e98bf80074be4654faae42fe0f5a622a776b6fdd:
>
> ARM: DRA7: clockdomain: Change the CLKTRCTRL of CM_PCIE_CLKSTCTRL to SW_WKUP (2017-03-27 15:08:22 +0530)
>
> ----------------------------------------------------------------
FWIW:
I've tested Kishon's tag pci-endpoint-for-4.12
and PCIe on artpec6 SoC is still working fine.
I also included the DRA7xx PCIe driver in my
kernel so that pcie-designware-ep.c gets built.
My only worry is that the code in pcie-designware-ep.c
is not compile tested if DRA7xx is not selected
(as it is the only driver using PCIE_DW_EP at
the moment).
^ permalink raw reply
* Re: [PATCH v2 2/7] dt-bindings: pinctrl: Add RZ/A1 bindings doc
From: jacopo @ 2017-03-29 12:05 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Linus Walleij, Jacopo Mondi, Geert Uytterhoeven, Laurent Pinchart,
Chris Brandt, Rob Herring, Mark Rutland, Russell King,
Linux-Renesas, linux-gpio@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CAMuHMdX0OdZXYDOZvFutjfBFVd65C567_G+++kHygre4KK+jLg@mail.gmail.com>
Hi Geert, Linus
On Wed, Mar 29, 2017 at 01:20:39PM +0200, Geert Uytterhoeven wrote:
> Hi Linus,
>
> On Wed, Mar 29, 2017 at 12:15 PM, Linus Walleij
> <linus.walleij@linaro.org> wrote:
> > On Wed, Mar 29, 2017 at 9:35 AM, Geert Uytterhoeven
> > <geert@linux-m68k.org> wrote:
> >>> See for example:
> >>> include/dt-bindings/pinctrl/mt65xx.h
> >>>
> >>> And how that is used in:
> >>> arch/arm/boot/dts/mt2701-pinfunc.h
> >>> arch/arm/boot/dts/mt2701-evb.dts
> >>>
> >>> The docs are here:
> >>> Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
> >>
> >> All of the above pack the information for a pin into a single 32-bit integer.
> >> Is that what you want us to use, too?
> >> Currently we use two integers: 1) pin index, and 2) function/flags combo.
> >
> > I don't really know what you need, sorry. But some kind of figure, yes.
> > I would say whatever makes sense. 16+16 bits makes sense in most
> > combinatorial spaces does it not? If you split 32 bits in 16 bits for
> > pin and 16 bits for function, do you have more than 2^16 pins or 2^16
> > functions?
> >
> > If you really do we may need to go for u64 but ... really? Is there
> > a rational reason for that other than "we did it like this first"?
> >
> > I do not understand the notion of "flags" here. I hope that is not referring
>
> Flags refers to BI_DIR, SWIO_IN, and SWIO_OUT, from
> https://patchwork.kernel.org/patch/9643047/
>
> 32-bit should be enough to cover pins, function, and flags.
>
Geert already replied, but to avoid any confusion I'll try to remove
from driver the use of "pin config" when referring to this three
flags, which are just additional informations the pin controller needs
to perform pin muxing properly. They're not related the standard pin
config properties (pull-up/down, bias etc.. actually our hardware does
not even support these natively)
> > to pin config, because I expect that to use the standard pin config
> > bindings outside of the pinmux value which should just define the
> > pin+function combo:
> >
> > node {
> > pinmux = <PIN_NUMBER_PINMUX>;
> > GENERIC_PINCONFIG;
> > };
> >
> > Example from Mediatek:
> >
> > i2c1_pins_a: i2c1@0 {
> > pins {
> > pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
> > <MT8135_PIN_196_SCL1__FUNC_SCL1>;
>
> If we follow this example, then we can list all combinations in
> include/dt-bindings/pinctrl/r7s72100-pinctrl.h, instead of creating the value
> by combining the bits using a macro where we need it in the DTS.
>
> It's gonna be a long list, though...
>
I'm strongly in favour of something like
pinmux = <PIN(1, 4) | FUNC# | FLAGS>, .... ;
opposed to
pinmux = <PIN1_4_FUNC#_FLAGS>, ... ;
Not only because it will save use from having a loong list(*) of macros that has
to be kept up to date when/if new RZ hardware will arrive, but also
because of readability and simplicity for down-stream and BSP users.
Speaking of which, I would like to know what does Chris think of this.
Is there any strong preference between the two for you Linus?
Thanks
j
(*) 12 ports, 16 pins, 8 functions, 3 flags: you can do the math
yourselves and see this is going to be hard to maintain.
> > bias-pull-up = <55>;
> > };
> > };
> >
> > So this allows for a combine pin+function number but pull ups,
> > bias etc are not baked into the thing, they have to be added on
> > separately with the generic bindings, which is nice and very readable.
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
^ permalink raw reply
* Re: [GIT PULL] PCI: Support for configurable PCI endpoint
From: Kishon Vijay Abraham I @ 2017-03-29 12:10 UTC (permalink / raw)
To: Niklas Cassel, Bjorn Helgaas, Joao Pinto, linux-pci, linux-doc,
linux-kernel, devicetree, linux-omap, linux-arm-kernel
Cc: hch, nsekhar
In-Reply-To: <0cfe5acf-332c-00c9-e5d5-1403c4e80ebe@axis.com>
Hi Niklas,
On Wednesday 29 March 2017 05:12 PM, Niklas Cassel wrote:
> On 03/27/2017 11:44 AM, Kishon Vijay Abraham I wrote:
>> Hi Bjorn,
>>
>> Please find the pull request for PCI endpoint support below. I've
>> also included all the history here.
>>
>> Changes from v4:
>> *) add #syscon-cells property and used of_parse_phandle_with_args
>> to perform a configuration in syscon module (as suggested by
>> Rob Herring)
>> *) Remove unnecessary white space.
>>
>> Changes from v3:
>> *) fixed a typo and adapted to https://lkml.org/lkml/2017/3/13/562.
>>
>> Changes from v2:
>> *) changed the configfs structure as suggested by Christoph Hellwig. With
>> this change the framework creates configfs entry for EP function driver
>> and EP controller. Previously these entries have to be created by the
>> the user. (Haven't changed the epc core or epf core except for invoking
>> configfs APIs to create entries for EP function driver and EP controller.
>> That's mostly because the EP function device can still be created by
>> directly invoking the epf core API without using configfs).
>> *) Now the user has to use configfs entry 'start' to start the link.
>> This was previously done by the function driver. However in the case of
>> multi function EP, the function driver shouldn't start the link.
>>
>> Changes from v1:
>> *) The preparation patches for adding EP support is removed and is sent
>> separately
>> *) Added device ID for DRA74x/DRA72x and used it instead of
>> using "PCI_ANY_ID"
>> *) Added userguide for PCI endpoint test function
>>
>> Major Improvements from RFC:
>> *) support multi-function devices (hw supported not virtual)
>> *) Access host side buffers
>> *) Raise MSI interrupts
>> *) Add user space program to use the host side PCI driver
>> *) Adapt all other users of designware to use the new design (only
>> compile tested. Since I have only dra7xx boards, the new design
>> has only been tested in dra7xx. I'd require the help of others
>> to test the platforms they have access to).
>>
>> This series has been developed over 4.11-rc1 + [1]
>> [1] -> https://lkml.org/lkml/2017/3/13/562
>>
>> Let me know if this has to be re-based to some of your branch.
>>
>> Thanks
>> Kishon
>>
>> The following changes since commit 623e87fec8ab7867fb51b3079196bd10718a60ce:
>>
>> PCI: dwc: dra7xx: Push request_irq call to the bottom of probe (2017-03-22 20:35:30 +0530)
>>
>> are available in the git repository at:
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git tags/pci-endpoint-for-4.12
>>
>> for you to fetch changes up to e98bf80074be4654faae42fe0f5a622a776b6fdd:
>>
>> ARM: DRA7: clockdomain: Change the CLKTRCTRL of CM_PCIE_CLKSTCTRL to SW_WKUP (2017-03-27 15:08:22 +0530)
>>
>> ----------------------------------------------------------------
>
> FWIW:
> I've tested Kishon's tag pci-endpoint-for-4.12
> and PCIe on artpec6 SoC is still working fine.
Thanks for testing it.
>
> I also included the DRA7xx PCIe driver in my
> kernel so that pcie-designware-ep.c gets built.
>
> My only worry is that the code in pcie-designware-ep.c
> is not compile tested if DRA7xx is not selected
> (as it is the only driver using PCIE_DW_EP at
> the moment).
yeah, we should plan to include COMPILE_TEST in all pci drivers but I guess
there is some problem with non-ARM builds [1]. As Bjorn mentioned in the
thread, we could add #ifdef ARM and then include COMPILE_TEST.
Thanks
Kishon
[1] -> http://www.spinics.net/lists/linux-pci/msg58134.html
Thanks
Kishon
>
^ permalink raw reply
* Re: [PATCH v6 1/5] irqchip/aspeed-i2c-ic: binding docs for Aspeed I2C Interrupt Controller
From: Benjamin Herrenschmidt @ 2017-03-29 12:11 UTC (permalink / raw)
To: Brendan Higgins
Cc: Wolfram Sang, robh+dt, mark.rutland, tglx, jason, Marc Zyngier,
Joel Stanley, Vladimir Zapolskiy, Kachalov Anton,
Cédric Le Goater, linux-i2c, devicetree, linux-kernel,
OpenBMC Maillist
In-Reply-To: <CAFd5g47Pij6TxkmS6akWoAL0FZ2WLh+FWUrr099RiabWn+pneQ@mail.gmail.com>
On Wed, 2017-03-29 at 03:34 -0700, Brendan Higgins wrote:
> I think I addressed this on the other email with the actual driver.
> Anyway, I thought that this is pretty much the dummy irqchip code is
> for; I have seen some other drivers do the same thing. It is true
> that
> this is a really basic "interrupt controller;" it cannot mask on its
> own, etc; nevertheless, I think you will pretty much end up with the
> same code for an "I2C controller;" it just won't use an irq_domain.
Don't worry too much about this. As I think I mention it's not a huge
deal at this stage, I just wanted to make sure you were aware of the
compromise(s) involved.
Regarding the other comment about the "fast mode", my main worry here
is that somebody might come up with a 2Mhz capable device, we'll hit
your 1Mhz test, enable fast mode, and shoot it with 3.4Mhz which it
might not be happy at all about...
I think the cut-off for switching to the "fast" mode should basically
be the fast speed mode frequency (which isn't clear from the spec but
seems to be 3.4Mhz). Otherwise people will end up with higher speeds
than what they asked for and that's bad.
Cheers,
Ben.
^ permalink raw reply
* [PATCHv5] mfd: cpcap: implement irq sense helper
From: Sebastian Reichel @ 2017-03-29 12:18 UTC (permalink / raw)
To: Sebastian Reichel, Lee Jones
Cc: Tony Lindgren, Dmitry Torokhov, Rob Herring, Mark Rutland,
linux-input, devicetree, linux-kernel
In-Reply-To: <20170329080423.ijbl4seczla2s4nm@dell>
CPCAP can sense if IRQ is currently set or not. This
functionality is required for a few subdevices, such
as the power button and usb phy modules.
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
Changes since PATCHv3:
- add extern to function definition
- use BIT macro for mask variable
- avoid magic numbers
Changes since PATCHv4:
- rename base to irq_base
---
drivers/mfd/motorola-cpcap.c | 28 ++++++++++++++++++++++++++++
include/linux/mfd/motorola-cpcap.h | 2 ++
2 files changed, 30 insertions(+)
diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c
index 6aeada7d7ce5..a9097efcefa5 100644
--- a/drivers/mfd/motorola-cpcap.c
+++ b/drivers/mfd/motorola-cpcap.c
@@ -23,6 +23,8 @@
#define CPCAP_NR_IRQ_REG_BANKS 6
#define CPCAP_NR_IRQ_CHIPS 3
+#define CPCAP_REGISTER_SIZE 4
+#define CPCAP_REGISTER_BITS 16
struct cpcap_ddata {
struct spi_device *spi;
@@ -32,6 +34,32 @@ struct cpcap_ddata {
struct regmap *regmap;
};
+static int cpcap_sense_irq(struct regmap *regmap, int irq)
+{
+ int regnum = irq / CPCAP_REGISTER_BITS;
+ int mask = BIT(irq % CPCAP_REGISTER_BITS);
+ int reg = CPCAP_REG_INTS1 + (regnum * CPCAP_REGISTER_SIZE);
+ int err, val;
+
+ if (reg < CPCAP_REG_INTS1 || reg > CPCAP_REG_INTS4)
+ return -EINVAL;
+
+ err = regmap_read(regmap, reg, &val);
+ if (err)
+ return err;
+
+ return !!(val & mask);
+}
+
+int cpcap_sense_virq(struct regmap *regmap, int virq)
+{
+ struct regmap_irq_chip_data *d = irq_get_chip_data(virq);
+ int irq_base = regmap_irq_chip_get_base(d);
+
+ return cpcap_sense_irq(regmap, virq - irq_base);
+}
+EXPORT_SYMBOL_GPL(cpcap_sense_virq);
+
static int cpcap_check_revision(struct cpcap_ddata *cpcap)
{
u16 vendor, rev;
diff --git a/include/linux/mfd/motorola-cpcap.h b/include/linux/mfd/motorola-cpcap.h
index b4031c2b2214..793aa695faa0 100644
--- a/include/linux/mfd/motorola-cpcap.h
+++ b/include/linux/mfd/motorola-cpcap.h
@@ -290,3 +290,5 @@ static inline int cpcap_get_vendor(struct device *dev,
return 0;
}
+
+extern int cpcap_sense_virq(struct regmap *regmap, int virq);
--
2.11.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox