* [PATCH v5 08/11] drm/sun4i: tcon: add support for V3s TCON
From: Icenowy Zheng @ 2017-04-23 10:37 UTC (permalink / raw)
To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170423103754.50012-1-icenowy-h8G6r0blFSE@public.gmane.org>
Allwinner V3s SoC features a TCON without channel 1.
Add support for it.
Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
---
drivers/gpu/drm/sun4i/sun4i_drv.c | 3 ++-
drivers/gpu/drm/sun4i/sun4i_tcon.c | 5 +++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 68c0b754cdb5..736b28e47281 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -176,7 +176,8 @@ static bool sun4i_drv_node_is_tcon(struct device_node *node)
return of_device_is_compatible(node, "allwinner,sun5i-a13-tcon") ||
of_device_is_compatible(node, "allwinner,sun6i-a31-tcon") ||
of_device_is_compatible(node, "allwinner,sun6i-a31s-tcon") ||
- of_device_is_compatible(node, "allwinner,sun8i-a33-tcon");
+ of_device_is_compatible(node, "allwinner,sun8i-a33-tcon") ||
+ of_device_is_compatible(node, "allwinner,sun8i-v3s-tcon");
}
static int compare_of(struct device *dev, void *data)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index e4fef0639656..c8e695d5776b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -533,11 +533,16 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
/* nothing is supported */
};
+static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
+ /* nothing is supported */
+};
+
static const struct of_device_id sun4i_tcon_of_table[] = {
{ .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks },
{ .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
{ .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
{ .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
+ { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
{ }
};
MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
--
2.12.2
^ permalink raw reply related
* [PATCH v5 09/11] ARM: dts: sun8i: add DE2 nodes for V3s SoC
From: Icenowy Zheng @ 2017-04-23 10:37 UTC (permalink / raw)
To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170423103754.50012-1-icenowy-h8G6r0blFSE@public.gmane.org>
Allwinner V3s SoC features a "Display Engine 2.0" with only one TCON
which have RGB LCD output.
Add device nodes for it as well as the TCON.
Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
---
arch/arm/boot/dts/sun8i-v3s.dtsi | 87 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index 71075969e5e6..0a895179d8ae 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -41,6 +41,10 @@
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun8i-v3s-ccu.h>
+#include <dt-bindings/clock/sun8i-de2.h>
+#include <dt-bindings/reset/sun8i-v3s-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
/ {
#address-cells = <1>;
@@ -59,6 +63,12 @@
};
};
+ de: display-engine {
+ compatible = "allwinner,sun8i-v3s-display-engine";
+ allwinner,pipelines = <&de2_mixer0>;
+ status = "disabled";
+ };
+
timer {
compatible = "arm,armv7-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
@@ -93,6 +103,83 @@
#size-cells = <1>;
ranges;
+ de2_clocks: clock@1000000 {
+ compatible = "allwinner,sun50i-h5-de2-clk";
+ reg = <0x01000000 0x100000>;
+ clocks = <&ccu CLK_DE>,
+ <&ccu CLK_BUS_DE>;
+ clock-names = "mod",
+ "bus";
+ resets = <&ccu RST_BUS_DE>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ de2_mixer0: mixer@1100000 {
+ compatible = "allwinner,sun8i-v3s-de2-mixer";
+ reg = <0x01100000 0x100000>;
+ clocks = <&de2_clocks CLK_MIXER0>,
+ <&de2_clocks CLK_BUS_MIXER0>;
+ clock-names = "mod",
+ "bus";
+ resets = <&de2_clocks RST_MIXER0>;
+ assigned-clocks = <&de2_clocks CLK_MIXER0>;
+ assigned-clock-rates = <150000000>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mixer0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ mixer0_out_tcon0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&tcon0_in_mixer0>;
+ };
+ };
+ };
+ };
+
+ tcon0: lcd-controller@1c0c000 {
+ compatible = "allwinner,sun8i-v3s-tcon";
+ reg = <0x01c0c000 0x1000>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_TCON0>,
+ <&ccu CLK_TCON0>;
+ clock-names = "ahb",
+ "tcon-ch0";
+ clock-output-names = "tcon-pixel-clock";
+ resets = <&ccu RST_BUS_TCON0>;
+ reset-names = "lcd";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tcon0_in: port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ tcon0_in_mixer0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&mixer0_out_tcon0>;
+ };
+ };
+
+ tcon0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+ };
+ };
+
+
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun7i-a20-mmc";
reg = <0x01c0f000 0x1000>;
--
2.12.2
^ permalink raw reply related
* [PATCH v5 10/11] ARM: dts: sun8i: add pinmux for LCD pins of V3s SoC
From: Icenowy Zheng @ 2017-04-23 10:37 UTC (permalink / raw)
To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170423103754.50012-1-icenowy-h8G6r0blFSE@public.gmane.org>
Allwinner V3s SoC features a set of pins that have functionality of RGB
LCD, the pins are at different pin ban than other SoCs.
Add pinctrl node for them.
Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
---
arch/arm/boot/dts/sun8i-v3s.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index 0a895179d8ae..a37d68b227bc 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -297,6 +297,15 @@
function = "i2c0";
};
+ lcd_rgb666_pins: lcd_rgb666@0 {
+ pins = "PE0", "PE1", "PE2", "PE3", "PE4",
+ "PE5", "PE6", "PE7", "PE8", "PE9",
+ "PE10", "PE11", "PE12", "PE13", "PE14",
+ "PE15", "PE16", "PE17", "PE18", "PE19",
+ "PE23", "PE24";
+ function = "lcd";
+ };
+
uart0_pins_a: uart0@0 {
pins = "PB8", "PB9";
function = "uart0";
--
2.12.2
^ permalink raw reply related
* [PATCH v5 11/11] [DO NOT MERGE] ARM: dts: sun8i: enable LCD panel of Lichee Pi Zero
From: Icenowy Zheng @ 2017-04-23 10:37 UTC (permalink / raw)
To: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec
Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170423103754.50012-1-icenowy-h8G6r0blFSE@public.gmane.org>
A 480x272 QiaoDian QD43003C0-40-7LED panel is available from Lichee Pi.
This commit connects this panel to Lichee Pi Zero.
Lichee Pi also provides a 800x480 panel without accurate model number,
so do not merge this patch. It will finally come as device tree overlay.
Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
---
arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts | 36 +++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
index 387fc2aa546d..7ae72bf63cd0 100644
--- a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
+++ b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
@@ -75,6 +75,28 @@
gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
};
};
+
+ panel: panel {
+ compatible = "qiaodian,qd43003c0-40", "simple-panel";
+ enable-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* Should be backlight */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel_input: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&tcon0_out_lcd>;
+ };
+ };
+ };
+};
+
+&de {
+ status = "okay";
};
&mmc0 {
@@ -86,6 +108,20 @@
status = "okay";
};
+&tcon0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_rgb666_pins>;
+ status = "okay";
+
+};
+
+&tcon0_out {
+ tcon0_out_lcd: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&panel_input>;
+ };
+};
+
&uart0 {
pinctrl-0 = <&uart0_pins_a>;
pinctrl-names = "default";
--
2.12.2
^ permalink raw reply related
* [PATCH 0/2] Lattice MachXO2 Passive SPI FPGA Manager support
From: Paolo Pisati @ 2017-04-23 15:20 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Alan Tull, Moritz Fischer
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-fpga-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Hi all,
this series adds support for the Lattice MachXO2 FPGA chip, programmed
over Slave SPI.
Tested on my raspberry pi3 + bugblat's pif2 fpga hat.
Paolo Pisati (2):
dt: bindings: fpga: add lattice machxo2 slave spi binding description
fpga: lattice machxo2: Add Lattice MachXO2 support
.../bindings/fpga/lattice-machxo2-spi.txt | 29 +++
drivers/fpga/Kconfig | 7 +
drivers/fpga/Makefile | 1 +
drivers/fpga/machxo2-spi.c | 199 +++++++++++++++++++++
4 files changed, 236 insertions(+)
create mode 100644 Documentation/devicetree/bindings/fpga/lattice-machxo2-spi.txt
create mode 100644 drivers/fpga/machxo2-spi.c
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/2] dt: bindings: fpga: add lattice machxo2 slave spi binding description
From: Paolo Pisati @ 2017-04-23 15:20 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Alan Tull, Moritz Fischer
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-fpga-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1492960845-342-1-git-send-email-p.pisati-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Add dt binding documentation details for Lattice MachXO2 FPGA configuration
over Slave SPI interface.
Signed-off-by: Paolo Pisati <p.pisati-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../bindings/fpga/lattice-machxo2-spi.txt | 29 ++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 Documentation/devicetree/bindings/fpga/lattice-machxo2-spi.txt
diff --git a/Documentation/devicetree/bindings/fpga/lattice-machxo2-spi.txt b/Documentation/devicetree/bindings/fpga/lattice-machxo2-spi.txt
new file mode 100644
index 0000000..c3ef26bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/lattice-machxo2-spi.txt
@@ -0,0 +1,29 @@
+Lattice MachXO2 Slave SPI FPGA Manager
+
+Lattice MachXO2 FPGAs support a method of loading the bitstream over
+'slave SPI' interface.
+
+See 'MachXO2ProgrammingandConfigurationUsageGuide.pdf' on www.latticesemi.com
+
+Required properties:
+- compatible: should contain "lattice,machxo2-slave-spi"
+- reg: spi chip select of the FPGA
+
+Example for full FPGA configuration:
+
+ fpga-region0 {
+ compatible = "fpga-region";
+ fpga-mgr = <&fpga_mgr_spi>;
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ };
+
+ spi1: spi@2000 {
+ ...
+
+ fpga_mgr_spi: fpga-mgr@0 {
+ compatible = "lattice,machxo2-slave-spi";
+ spi-max-frequency = <60000000>;
+ reg = <0>;
+ };
+ };
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 2/2] fpga: lattice machxo2: Add Lattice MachXO2 support
From: Paolo Pisati @ 2017-04-23 15:20 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Alan Tull, Moritz Fischer
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-fpga-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1492960845-342-1-git-send-email-p.pisati-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Add support for the Lattice MachXO2 FPGA chip in Slave SPI configuration.
Signed-off-by: Paolo Pisati <p.pisati-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/fpga/Kconfig | 7 ++
drivers/fpga/Makefile | 1 +
drivers/fpga/machxo2-spi.c | 199 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 207 insertions(+)
create mode 100644 drivers/fpga/machxo2-spi.c
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index c81cb7d..cce135b 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -26,6 +26,13 @@ config FPGA_MGR_ICE40_SPI
help
FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
+config FPGA_MGR_MACHXO2_SPI
+ tristate "Lattice MachXO2 SPI"
+ depends on SPI
+ help
+ FPGA manager driver support for Lattice MachXO2 configuration
+ over slave SPI interface.
+
config FPGA_MGR_SOCFPGA
tristate "Altera SOCFPGA FPGA Manager"
depends on ARCH_SOCFPGA || COMPILE_TEST
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index c6f5d74..cdab1fe 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o
# FPGA Manager Drivers
obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o
+obj-$(CONFIG_FPGA_MGR_MACHXO2_SPI) += machxo2-spi.o
obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o
diff --git a/drivers/fpga/machxo2-spi.c b/drivers/fpga/machxo2-spi.c
new file mode 100644
index 0000000..5ee56bd
--- /dev/null
+++ b/drivers/fpga/machxo2-spi.c
@@ -0,0 +1,199 @@
+/**
+ * Lattice MachXO2 Slave SPI Driver
+ *
+ * Copyright (C) 2017 Paolo Pisati <p.pisati-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * Manage Lattice FPGA firmware that is loaded over SPI using
+ * the slave serial configuration interface.
+ */
+
+#include <linux/delay.h>
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/spi/spi.h>
+
+
+/* MachXO2 Programming Guide - sysCONFIG Programming Commands */
+
+#define ISC_ENABLE 0x000008c6
+#define ISC_ERASE 0x0000040e
+#define ISC_PROGRAMDONE 0x0000005e
+#define LSC_CHECKBUSY 0x000000f0
+#define LSC_INITADDRESS 0x00000046
+#define LSC_PROGINCRNV 0x01000070
+#define LSC_REFRESH 0x00000079
+
+/*
+ * Max CCLK in Slave SPI mode according to 'MachXO2 Family Data
+ * Sheet' sysCONFIG Port Timing Specifications (3-36)
+ */
+#define MACHXO2_MAX_SPEED 66000000
+
+#define MACHXO2_LOW_DELAY 5 /* us */
+#define MACHXO2_HIGH_DELAY 200 /* us */
+
+#define MACHXO2_OP_SIZE sizeof(uint32_t)
+#define MACHXO2_PAGE_SIZE 16
+#define MACHXO2_BUF_SIZE (MACHXO2_OP_SIZE + MACHXO2_PAGE_SIZE)
+
+
+static int waituntilnotbusy(struct spi_device *spi)
+{
+ uint8_t rx, busyflag = 0x80;
+ uint32_t checkbusy = LSC_CHECKBUSY;
+
+ do {
+ if (spi_write_then_read(spi, &checkbusy, MACHXO2_OP_SIZE,
+ &rx, sizeof(rx)))
+ return -EIO;
+ } while (rx & busyflag);
+ return 0;
+}
+
+static enum fpga_mgr_states machxo2_spi_state(struct fpga_manager *mgr)
+{
+ return FPGA_MGR_STATE_UNKNOWN;
+}
+
+static int machxo2_write_init(struct fpga_manager *mgr,
+ struct fpga_image_info *info,
+ const char *buf, size_t count)
+{
+ struct spi_device *spi = mgr->priv;
+ uint32_t enable = ISC_ENABLE;
+ uint32_t erase = ISC_ERASE;
+ uint32_t initaddr = LSC_INITADDRESS;
+
+ if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ dev_err(&mgr->dev,
+ "Partial reconfiguration is not supported\n");
+ return -ENOTSUPP;
+ }
+
+ if (spi_write(spi, &enable, MACHXO2_OP_SIZE))
+ goto fail;
+ udelay(MACHXO2_LOW_DELAY);
+ if (spi_write(spi, &erase, MACHXO2_OP_SIZE))
+ goto fail;
+ waituntilnotbusy(spi);
+ if (spi_write(spi, &initaddr, MACHXO2_OP_SIZE))
+ goto fail;
+ return 0;
+
+fail:
+ dev_err(&mgr->dev, "Error during FPGA init.\n");
+ return -EIO;
+}
+
+static int machxo2_write(struct fpga_manager *mgr, const char *buf,
+ size_t count)
+{
+ struct spi_device *spi = mgr->priv;
+ uint32_t progincr = LSC_PROGINCRNV;
+ uint8_t payload[MACHXO2_BUF_SIZE];
+ int i;
+
+ if (count % MACHXO2_PAGE_SIZE != 0) {
+ dev_err(&mgr->dev, "Malformed payload.\n");
+ return -EINVAL;
+ }
+
+ memcpy(payload, &progincr, MACHXO2_OP_SIZE);
+ for (i = 0; i < count; i += MACHXO2_PAGE_SIZE) {
+ memcpy(&payload[MACHXO2_OP_SIZE], &buf[i], MACHXO2_PAGE_SIZE);
+ if (spi_write(spi, payload, MACHXO2_BUF_SIZE)) {
+ dev_err(&mgr->dev, "Error loading the bitstream.\n");
+ return -EIO;
+ }
+ udelay(MACHXO2_HIGH_DELAY);
+ }
+
+ return 0;
+}
+
+static int machxo2_write_complete(struct fpga_manager *mgr,
+ struct fpga_image_info *info)
+{
+ struct spi_device *spi = mgr->priv;
+ uint32_t progdone = ISC_PROGRAMDONE;
+ uint32_t refresh = LSC_REFRESH;
+
+ if (spi_write(spi, &progdone, MACHXO2_OP_SIZE))
+ goto fail;
+ /* yep, LSC_REFRESH is 3 bytes long actually */
+ if (spi_write(spi, &refresh, MACHXO2_OP_SIZE-1))
+ goto fail;
+ return 0;
+
+fail:
+ dev_err(&mgr->dev, "Refresh failed.\n");
+ return -EIO;
+}
+
+static const struct fpga_manager_ops machxo2_ops = {
+ .state = machxo2_spi_state,
+ .write_init = machxo2_write_init,
+ .write = machxo2_write,
+ .write_complete = machxo2_write_complete,
+};
+
+static int machxo2_spi_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ int ret = 0;
+
+ if (spi->max_speed_hz > MACHXO2_MAX_SPEED) {
+ dev_err(dev, "Speed is too high\n");
+ return -EINVAL;
+ }
+
+ ret = fpga_mgr_register(dev, "Lattice MachXO2 SPI FPGA Manager",
+ &machxo2_ops, spi);
+ if (ret)
+ dev_err(dev, "Unable to register FPGA manager");
+
+ return ret;
+}
+
+static int machxo2_spi_remove(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+
+ fpga_mgr_unregister(dev);
+ return 0;
+}
+
+static const struct of_device_id of_match[] = {
+ { .compatible = "lattice,machxo2-slave-spi", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, of_match);
+
+static const struct spi_device_id lattice_ids[] = {
+ { "machxo2-slave-spi", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, lattice_ids);
+
+static struct spi_driver machxo2_spi_driver = {
+ .driver = {
+ .name = "machxo2-slave-spi",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(of_match),
+ },
+ .probe = machxo2_spi_probe,
+ .remove = machxo2_spi_remove,
+ .id_table = lattice_ids,
+};
+
+module_spi_driver(machxo2_spi_driver)
+
+MODULE_AUTHOR("Paolo Pisati <p.pisati-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("Load Lattice FPGA firmware over SPI");
+MODULE_LICENSE("GPL v2");
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [04/13] watchdog: lantiq: access boot cause register through regmap
From: Guenter Roeck @ 2017-04-23 15:48 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: ralf-6z/3iImG2C8G8FEW9MqTrA, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg,
john-Pj+rj9U5foFAfugRpC6u6w, linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20170417192942.32219-5-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
On Mon, Apr 17, 2017 at 09:29:33PM +0200, Hauke Mehrtens wrote:
> This patch avoids accessing the function ltq_reset_cause() and directly
> accesses the register given over the syscon interface. The syscon
> interface will be implemented for the xway SoCs for the falcon SoCs the
> ltq_reset_cause() function never worked, because a wrong offset was used.
>
> Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
Acked-by: Guenter Roeck <linux-cYGBoTPqujPR7s880joybQ@public.gmane.org>
> ---
> drivers/watchdog/lantiq_wdt.c | 47 +++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 43 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
> index e0823677d8c1..0e349ad03fdf 100644
> --- a/drivers/watchdog/lantiq_wdt.c
> +++ b/drivers/watchdog/lantiq_wdt.c
> @@ -17,9 +17,14 @@
> #include <linux/uaccess.h>
> #include <linux/clk.h>
> #include <linux/io.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
>
> #include <lantiq_soc.h>
>
> +#define LTQ_RST_CAUSE_WDT_XRX BIT(31)
> +#define LTQ_RST_CAUSE_WDT_FALCON 0x02
> +
> /*
> * Section 3.4 of the datasheet
> * The password sequence protects the WDT control register from unintended
> @@ -186,6 +191,40 @@ static struct miscdevice ltq_wdt_miscdev = {
> .fops = <q_wdt_fops,
> };
>
> +static void ltq_set_wdt_bootstatus(struct platform_device *pdev)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + struct regmap *rcu_regmap;
> + u32 status_reg_offset;
> + u32 val;
> + int err;
> +
> + rcu_regmap = syscon_regmap_lookup_by_phandle(np,
> + "lantiq,rcu-syscon");
> + if (IS_ERR_OR_NULL(rcu_regmap))
> + return;
> +
> + err = of_property_read_u32_index(np, "lantiq,rcu-syscon", 1,
> + &status_reg_offset);
> + if (err) {
> + dev_err(&pdev->dev, "Failed to get RCU reg offset\n");
> + return;
> + }
> +
> + err = regmap_read(rcu_regmap, status_reg_offset, &val);
> + if (err)
> + return;
> +
> + /* find out if the watchdog caused the last reboot */
> + if (of_device_is_compatible(np, "lantiq,wdt-xrx100")) {
> + if (val & LTQ_RST_CAUSE_WDT_XRX)
> + ltq_wdt_bootstatus = WDIOF_CARDRESET;
> + } else if (of_device_is_compatible(np, "lantiq,wdt-falcon")) {
> + if ((val & 0x7) == LTQ_RST_CAUSE_WDT_FALCON)
> + ltq_wdt_bootstatus = WDIOF_CARDRESET;
> + }
> +}
> +
> static int
> ltq_wdt_probe(struct platform_device *pdev)
> {
> @@ -205,9 +244,7 @@ ltq_wdt_probe(struct platform_device *pdev)
> ltq_io_region_clk_rate = clk_get_rate(clk);
> clk_put(clk);
>
> - /* find out if the watchdog caused the last reboot */
> - if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST)
> - ltq_wdt_bootstatus = WDIOF_CARDRESET;
> + ltq_set_wdt_bootstatus(pdev);
>
> dev_info(&pdev->dev, "Init done\n");
> return misc_register(<q_wdt_miscdev);
> @@ -222,7 +259,9 @@ ltq_wdt_remove(struct platform_device *pdev)
> }
>
> static const struct of_device_id ltq_wdt_match[] = {
> - { .compatible = "lantiq,wdt" },
> + { .compatible = "lantiq,wdt"},
> + { .compatible = "lantiq,wdt-xrx100"},
> + { .compatible = "lantiq,wdt-falcon"},
> {},
> };
> MODULE_DEVICE_TABLE(of, ltq_wdt_match);
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] spi-imx: Implements handling of the SPI_READY mode flag.
From: Jonas Gorski @ 2017-04-23 18:43 UTC (permalink / raw)
To: Leif Middelschulte
Cc: Mark Brown, linux-spi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20170423111837.19460-1-Leif.Middelschulte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hi,
On 23 April 2017 at 13:18, Leif Middelschulte
<leif.middelschulte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> From: Leif Middelschulte <leif.middelschulte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> This patch implements consideration of the SPI_READY mode flag as
> defined in spi.h. It extends the device tree bindings to support
> the values defined by the reference manual for the DRCTL field.
>
> Thus supporting edge-triggered and level-triggered bursts.
>
> Signed-off-by: Leif Middelschulte <Leif.Middelschulte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> .../devicetree/bindings/spi/fsl-imx-cspi.txt | 5 +++++
> drivers/spi/spi-imx.c | 23 ++++++++++++++++++++--
> 2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
> index 8bc95e2fc47f..890b3ff3325f 100644
> --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
> +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
You are modifying device tree documentation, you need to CC the
appropriate mailing list as well (as I now did).
> @@ -23,6 +23,10 @@ See the clock consumer binding,
> Obsolete properties:
> - fsl,spi-num-chipselects : Contains the number of the chipselect
>
> +Optional properties:
> +- fsl,spi-drctl: Integer, representing the value of DRCTL. Note that to
> +enable the DRCTL consideration, the SPI_READY mode-flag needs to be set.
Maybe document the valid values here as well? Also spi-drctl isn't
really a nice name, maybe something human understandable that doesn't
require looking into the datasheet?
> +
> Example:
>
> ecspi@70010000 {
> @@ -35,4 +39,5 @@ ecspi@70010000 {
> <&gpio3 25 0>; /* GPIO3_25 */
> dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
> dma-names = "rx", "tx";
> + fsl,spi-drctl = <1>;
> };
> diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
> index 9a7c62f471dc..647a4bf18705 100644
> --- a/drivers/spi/spi-imx.c
> +++ b/drivers/spi/spi-imx.c
> @@ -95,6 +95,7 @@ struct spi_imx_data {
> unsigned int spi_bus_clk;
>
> unsigned int bytes_per_word;
> + unsigned int spi_drctl;
>
> unsigned int count;
> void (*tx)(struct spi_imx_data *);
> @@ -246,6 +247,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
> #define MX51_ECSPI_CTRL_XCH (1 << 2)
> #define MX51_ECSPI_CTRL_SMC (1 << 3)
> #define MX51_ECSPI_CTRL_MODE_MASK (0xf << 4)
> +#define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16)
> #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8
> #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12
> #define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18)
> @@ -355,6 +357,12 @@ static int mx51_ecspi_config(struct spi_device *spi,
> */
> ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
>
> + /*
> + * Enable SPI_RDY handling (falling edge/level triggered).
> + */
> + if (spi->mode & SPI_READY)
> + ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl);
> +
> /* set clock speed */
> ctrl |= mx51_ecspi_clkdiv(spi_imx, config->speed_hz, &clk);
> spi_imx->spi_bus_clk = clk;
> @@ -1173,7 +1181,7 @@ static int spi_imx_probe(struct platform_device *pdev)
> struct spi_master *master;
> struct spi_imx_data *spi_imx;
> struct resource *res;
> - int i, ret, irq;
> + int i, ret, irq, spi_drctl;
>
> if (!np && !mxc_platform_info) {
> dev_err(&pdev->dev, "can't get the platform data\n");
> @@ -1181,6 +1189,15 @@ static int spi_imx_probe(struct platform_device *pdev)
> }
>
> master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data));
> + ret = of_property_read_u32(np, "fsl,spi-drctl", &spi_drctl);
> + if ((ret < 0) || (spi_drctl == 0x3)) {
> + // '11' is reserved
Don't use C99 comments, use /* */ comments.
> + spi_drctl = 0;
Here you say '11' is reserved and force 0 if set
> + } else {
> + // only the values '00', '01' and '11' are valid
And here you say '11' is valid. So which is it? Did you mean '10'?
> + spi_drctl &= 0x3;
Also with this code flow if fsl,spi-drctl is set to <7>, it will cause
spi_drctl set to '11' / 0x3.
Maybe it would be easier to do
if (ret < 0 || spi_drctl >= 0x3)
spi_drctl = 0;
to only accept valid values. Assuming '11' is the invalid one and not '10'.
Regards
Jonas
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 6/9] staging: ccree: add FIPS support
From: Stephan Müller @ 2017-04-23 18:57 UTC (permalink / raw)
To: Gilad Ben-Yossef
Cc: Herbert Xu, David S. Miller, Rob Herring, Mark Rutland,
Greg Kroah-Hartman, devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Linux kernel mailing list,
Gilad Ben-Yossef, Binoy Jayan, Ofir Drang, Stuart Yoder
In-Reply-To: <CAOtvUMcOib2xr=THj1hy_uPtVhRHgJ2-4__mUBb5VwANQ1GA_A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Am Sonntag, 23. April 2017, 11:48:58 CEST schrieb Gilad Ben-Yossef:
Hi Gilad,
> I do wonder if there is value in alternate behavior of stopping crypto
> API on FIPS error rather than a panic though. I will try to get an
> explanation why we do it this way.
In FIPS, all crypto function must cease if a self test fails. This can be done
by instrumenting the crypto API calls with a check to a global flag or by
simply terminating the entire "FIPS module".
The panic() is the simplest approach to meet that requirement.
Ciao
Stephan
--
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] iio: adc: add driver for the ti-adc084s021 chip
From: Jonathan Cameron @ 2017-04-23 19:13 UTC (permalink / raw)
To: Peter Meerwald-Stadler, Mårten Lindahl
Cc: lars-Qo5EllUWu/uELgA04lAiVw, linux-iio-u79uwXL29TY76Z2rM5mHXA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
devicetree-u79uwXL29TY76Z2rM5mHXA, Mårten Lindahl
In-Reply-To: <alpine.DEB.2.20.1704212149070.2470-M0QeDd4q1oXQbIPoIc8EuQ@public.gmane.org>
On 21/04/17 21:19, Peter Meerwald-Stadler wrote:
>
>> From: Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>
>
> comments below
A few more from me. Laptop battery gone flat so not so thorough on top few lines!
Jonathan
>
>> This adds support for the Texas Instruments ADC084S021 ADC chip.
>>
>> Signed-off-by: Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>
>> ---
>> .../devicetree/bindings/iio/adc/ti-adc084s021.txt | 25 ++
>> drivers/iio/adc/Kconfig | 12 +
>> drivers/iio/adc/Makefile | 1 +
>> drivers/iio/adc/ti-adc084s021.c | 342 +++++++++++++++++++++
>> 4 files changed, 380 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
>> create mode 100644 drivers/iio/adc/ti-adc084s021.c
>>
>> diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
>> new file mode 100644
>> index 0000000..921eb46
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
>> @@ -0,0 +1,25 @@
>> +* Texas Instruments' ADC084S021
>> +
>> +Required properties:
>> + - compatible : Must be "ti,adc084s021"
>> + - reg : SPI chip select number for the device
>> + - vref-supply : The regulator supply for ADC reference voltage
>> + - spi-max-frequency : Definition as per Documentation/devicetree/bindings/spi/spi-bus.txt
>> +
>> +Optional properties:
>> + - spi-cpol : SPI inverse clock polarity, as per spi-bus bindings
>> + - spi-cpha : SPI shifted clock phase (CPHA), as per spi-bus bindings
>> + - spi-cs-high : SPI chip select active high, as per spi-bus bindings
>> +
>> +
>> +Example:
>> +adc@0 {
>> + compatible = "ti,adc084s021";
>> + reg = <0>;
>> + vref-supply = <&adc_vref>;
>> + spi-cpol;
>> + spi-cpha;
>> + spi-cs-high;
>> + spi-max-frequency = <16000000>;
>> + pl022,com-mode = <0x2>; /* DMA */
>
> what is this?
>
>> +};
>> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>> index dedae7a..13141e5 100644
>> --- a/drivers/iio/adc/Kconfig
>> +++ b/drivers/iio/adc/Kconfig
>> @@ -560,6 +560,18 @@ config TI_ADC0832
>> This driver can also be built as a module. If so, the module will be
>> called ti-adc0832.
>>
>> +config TI_ADC084S021
>> + tristate "Texas Instruments ADC084S021"
>> + depends on SPI
>> + select IIO_BUFFER
>> + select IIO_TRIGGERED_BUFFER
>> + help
>> + If you say yes here you get support for Texas Instruments ADC084S021
>> + chips.
>> +
>> + This driver can also be built as a module. If so, the module will be
>> + called ti-adc084s021.
>> +
>> config TI_ADC12138
>> tristate "Texas Instruments ADC12130/ADC12132/ADC12138"
>> depends on SPI
>> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
>> index d001262..b1a6158 100644
>> --- a/drivers/iio/adc/Makefile
>> +++ b/drivers/iio/adc/Makefile
>> @@ -51,6 +51,7 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
>> obj-$(CONFIG_STM32_ADC) += stm32-adc.o
>> obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
>> obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
>> +obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
>> obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
>> obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
>> obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
>> diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c
>> new file mode 100644
>> index 0000000..4f33b91
>> --- /dev/null
>> +++ b/drivers/iio/adc/ti-adc084s021.c
>> @@ -0,0 +1,342 @@
>> +/**
>> + * Copyright (C) 2017 Axis Communications AB
>> + *
>> + * Driver for Texas Instruments' ADC084S021 ADC chip.
>> + * Datasheets can be found here:
>> + * http://www.ti.com/lit/ds/symlink/adc084s021.pdf
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/err.h>
>> +#include <linux/spi/spi.h>
>> +#include <linux/module.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/iio/iio.h>
>> +#include <linux/iio/buffer.h>
>> +#include <linux/iio/events.h>
>> +#include <linux/iio/triggered_buffer.h>
>> +#include <linux/iio/trigger_consumer.h>
>> +#include <linux/regulator/consumer.h>
>> +
>> +#define MODULE_NAME "adc084s021"
>> +#define DRIVER_VERSION "1.0"
>
> is only used once at the very end...
>
>> +#define ADC_RESOLUTION 8
Put it inline...
>> +#define ADC_N_CHANNELS 4
Belongs inline. No additional info provided by having it here.
>
> we want a consistent prefix, such as ADC084S021_
>
>> +
>> +struct adc084s021_configuration {
>> + const struct iio_chan_spec *channels;
>> + u8 num_channels;
>
> no need for u8, perhaps unsigned?
>
>> +};
>> +
>> +struct adc084s021 {
>> + struct spi_device *spi;
>> + struct spi_message message;
>> + struct spi_transfer spi_trans[2];
>> + struct regulator *reg;
>> + struct mutex lock;
>> + /*
>> + * DMA (thus cache coherency maintenance) requires the
>> + * transfer buffers to live in their own cache lines.
>> + */
>> + union {
>> + u8 tx_buf[2];
>> + u8 rx_buf[2];
>> + } ____cacheline_aligned;
>> + u8 cur_adc_values[ADC_N_CHANNELS];
>> +};
>> +
>> +/**
>> + * Event triggered when value changes on a channel
>> + */
>> +static const struct iio_event_spec adc084s021_event = {
>> + .type = IIO_EV_TYPE_CHANGE,
>> + .dir = IIO_EV_DIR_NONE,
>> +};
Not the intent of that type of event at all.
>> +
>> +/**
>> + * Channel specification
>> + */
>> +#define ADC084S021_VOLTAGE_CHANNEL(num) \
>> + { \
>> + .type = IIO_VOLTAGE, \
>> + .channel = (num), \
>> + .address = (num << 3), \
>
> parenthesis should be around (num)
>
>> + .indexed = 1, \
>> + .scan_index = num, \
>
> parenthesis?
>
>> + .scan_type = { \
>> + .sign = 'u', \
>> + .realbits = 8, \
>> + .storagebits = 32, \
>> + .shift = 24 - ((num << 3)), \
>
> no need for (( )) around the expression, parenthesis should be around num
>
> the shift doesn't make sense, you are shifting in
>
> adc084s021_adc_conversion() already and return just 8 bits (so storagebits
> should be 8)?
>
> you could/should use realbits = 8, storagebits = 16, shift = 4 and
> endianness = IIO_BE if I read Figure 1 of the datasheet correctly
>
>> + }, \
>> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
>
> likely this is missing _SCALE
> IIO expects data to be returned in millivolt, see
> Documentation/ABI/testing/sysfs-bus-iio
>
>> + .event_spec = &adc084s021_event, \
>> + .num_event_specs = 1, \
>
> ARRAY_SIZE(&adc084s021_event) to be extensible?
>
>> + }
>> +
>> +static const struct iio_chan_spec adc084s021_channels[] = {
>> + ADC084S021_VOLTAGE_CHANNEL(0),
>> + ADC084S021_VOLTAGE_CHANNEL(1),
>> + ADC084S021_VOLTAGE_CHANNEL(2),
>> + ADC084S021_VOLTAGE_CHANNEL(3),
>> + IIO_CHAN_SOFT_TIMESTAMP(4),
>> +};
>> +
>> +static const struct adc084s021_configuration adc084s021_config[] = {
>> + { adc084s021_channels, ARRAY_SIZE(adc084s021_channels) },
>
> for just one configuration, this is not really needed; so you plan/forsee
> more chips being added soonish?
>
>> +};
>> +
>> +/**
>> + * Read an ADC channel and return its value.
>> + *
>> + * @adc: The ADC SPI data.
>> + * @channel: The IIO channel data structure.
>> + */
>> +static int adc084s021_adc_conversion(struct adc084s021 *adc,
>> + struct iio_chan_spec const *channel)
>> +{
>> + u16 value;
>
> value should be u8, but is not really needed
>
>> + int ret;
>> +
>> + mutex_lock(&adc->lock);
>> + adc->tx_buf[0] = channel->address;
>> +
>> + /* Do the transfer */
>> + ret = spi_sync(adc->spi, &adc->message);
>> +
>
> no newline here please
>
>> + if (ret < 0) {
>> + mutex_unlock(&adc->lock);
>> + return ret;
>> + }
>> +
>> + value = (adc->rx_buf[0] << 4) | (adc->rx_buf[1] >> 4);
>
> I recommend using __be16 for rx_buf and
> ret = (be16_to_cpu(adc->rx_buf) >> 4) & 0xff;
>
>> + mutex_unlock(&adc->lock);
>> +
>> + dev_dbg(&adc->spi->dev, "value 0x%02X on channel %d\n",
>> + value, channel->channel);
>> + return value;
>> +}
>> +
>> +/**
>> + * Make a readout of requested IIO channel info.
>
> no need to document this, it is found in every IIO driver...
>
>> + *
>> + * @indio_dev: The industrial I/O device.
>> + * @channel: The IIO channel data structure.
>> + * @val: First element of value (integer).
>> + * @val2: Second element of value (fractional).
>> + * @mask: The info_mask to read.
>> + */
>> +static int adc084s021_read_raw(struct iio_dev *indio_dev,
>> + struct iio_chan_spec const *channel, int *val,
>> + int *val2, long mask)
>> +{
>> + struct adc084s021 *adc = iio_priv(indio_dev);
>> + int retval;
>
> how about using ret everywhere?
Agreed.
>
>> +
>> + switch (mask) {
>> + case IIO_CHAN_INFO_RAW:
>
> probably want iio_device_claim_direct_mode() so to not interfere with
> buffered accessBorderline case as all you will do is queue up additional spi transfers.
At least after you have dropped the unusual events stuff.
Arguably this will mean sysfs reads could make the buffered data flow
less deterministic though so maybe on claiming direct mode (which
prevents it running concurrently with buffered capture.
>
>> + retval = adc084s021_adc_conversion(adc, channel);
>> + if (retval < 0)
>> + return retval;
>> +
>> + *val = retval;
>> + return IIO_VAL_INT;
>> +
>> + default:
>> + return -EINVAL;
>> + }
>> +}
>> +
>> +/**
>> + * Read enabled ADC channels and push data to the buffer.
>> + *
>> + * @irq: The interrupt number (not used).
>> + * @pollfunc: Pointer to the poll func.
>> + */
>> +static irqreturn_t adc084s021_trigger_handler(int irq, void *pollfunc)
>> +{
>> + struct iio_poll_func *pf = pollfunc;
>> + struct iio_dev *indio_dev = pf->indio_dev;
>> + struct adc084s021 *adc = iio_priv(indio_dev);
>> + u8 *data;
>> + s64 timestamp;
>> + int value, scan_index;
>> +
>> + data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
>
> pre-allocate buffer with maximum size statically; allocation is
> potentially expensive; don't forget space for the timestamp and padding...
>
>> + if (!data) {
>> + iio_trigger_notify_done(indio_dev->trig);
>> + return IRQ_NONE;
>> + }
>> +
>> + timestamp = iio_get_time_ns(indio_dev);
>> +
>> + for_each_set_bit(scan_index, indio_dev->active_scan_mask,
>> + indio_dev->masklength) {
>> + const struct iio_chan_spec *channel =
>> + &indio_dev->channels[scan_index];
>> + value = adc084s021_adc_conversion(adc, channel);
>
> lock is taken and released for each channel, probably want to do it just
> once?
>
>> + data[scan_index] = value;
>> +
>> + /*
>> + * Compare read data to previous read. If it differs send
>> + * event notification for affected channel.
>> + */
>> + if (adc->cur_adc_values[scan_index] != (u8)value) {
>
> cur_adc_values is not initialized (probably set to 0);
> so on first read, should the notification be sent?
? This is 'unusual' to say the least. Why the events given the data
is available via the buffer. If you really want to do this stuff, it
ought to be in userspace.
Are you trying to emulate the filtering input does?
>
>> + adc->cur_adc_values[scan_index] = (u8)value;
>> + iio_push_event(indio_dev,
>> + IIO_EVENT_CODE(IIO_VOLTAGE, 0,
>> + IIO_NO_MOD, IIO_EV_DIR_NONE,
>> + IIO_EV_TYPE_CHANGE,
>> + channel->channel, 0, 0),
>> + timestamp);
>> + dev_dbg(&indio_dev->dev,
>> + "new value on ch%d: 0x%02X (ts %llu)\n",
>> + channel->channel, value, timestamp);
>> + }
>> + }
>> +
>> + iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp);
>> + iio_trigger_notify_done(indio_dev->trig);
>> + kfree(data);
blank line here please.
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static const struct iio_info adc084s021_info = {
>> + .read_raw = adc084s021_read_raw,
>> + .driver_module = THIS_MODULE,
>> +};
>> +
>> +/**
>> + * Create and register ADC IIO device for SPI.
>
> comment is rather pointless
>
>> + */
>> +static int adc084s021_probe(struct spi_device *spi)
>> +{
>> + struct iio_dev *indio_dev;
>> + struct adc084s021 *adc;
>> + int config = spi_get_device_id(spi)->driver_data;
>> + int retval;
>
> ret maybe
>
>> +
>> + /* Allocate an Industrial I/O device */
>
> obviously...
:) Yeah, clear out any comments that don't tell us much.
>
>> + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
>> + if (!indio_dev) {
>> + dev_err(&spi->dev, "Failed to allocate IIO device\n");
>> + return -ENOMEM;
>> + }
>> +
>> + adc = iio_priv(indio_dev);
>> + adc->spi = spi;
>> + spi->bits_per_word = ADC_RESOLUTION;
This surprised me somewhat as I was expecting an odd value for this
(and was going to ask if standard power of 2 options would work).
If it had been inline, this would have required slightly less review
time which I always like (particularly when crammed into an airline seat!)
>> +
>> + /* Update the SPI device with config and connect the iio dev */
>> + retval = spi_setup(spi);
>> + if (retval) {
>> + dev_err(&spi->dev, "Failed to update SPI device\n");
>> + return retval;
>> + }
>> + spi_set_drvdata(spi, indio_dev);
>> +
>> + /* Initiate the Industrial I/O device */
:>> + indio_dev->dev.parent = &spi->dev;
>> + indio_dev->dev.of_node = spi->dev.of_node;
>> + indio_dev->name = spi_get_device_id(spi)->name;
>> + indio_dev->modes = INDIO_DIRECT_MODE;
>> + indio_dev->info = &adc084s021_info;
>> + indio_dev->channels = adc084s021_config[config].channels;
>> + indio_dev->num_channels = adc084s021_config[config].num_channels;
>
> could do it directly as long there is just one configuration
That would certainly be preferable unless V2 is going to show up
with multiple options!
>
>> +
>> + /* Create SPI transfer for channel reads */
>> + adc->spi_trans[0].tx_buf = &adc->tx_buf[0];
>> + adc->spi_trans[0].len = 2;
>> + adc->spi_trans[0].speed_hz = spi->max_speed_hz;
>> + adc->spi_trans[0].bits_per_word = spi->bits_per_word;
>> + adc->spi_trans[1].rx_buf = &adc->rx_buf[0];
>> + adc->spi_trans[1].len = 2;
>> + adc->spi_trans[1].speed_hz = spi->max_speed_hz;
>> + adc->spi_trans[1].bits_per_word = spi->bits_per_word;
>> +
>> + /* Setup SPI message for channel reads */
>> + spi_message_init(&adc->message);
>> + spi_message_add_tail(&adc->spi_trans[0], &adc->message);
>> + spi_message_add_tail(&adc->spi_trans[1], &adc->message);
spi_init_with_transfers to save a bit of boilerplate.
>> +
>> + adc->reg = devm_regulator_get(&spi->dev, "vref");
>> + if (IS_ERR(adc->reg))
>> + return PTR_ERR(adc->reg);
>> +
>> + retval = regulator_enable(adc->reg);
>> + if (retval < 0)
>> + return retval;
Given we either have slow sysfs accesses or know we have buffered
access on going. Have you considered enabling and disabling
the regulator dynamically? The fact that this often makes sense is
why Mark and co from the regulators side of things haven't provided
a devm_regulator_enable... You would need a preenable and postdisable
to make sure it was on for buffered access.
>> +
>> + mutex_init(&adc->lock);
>> +
>> + /* Setup triggered buffer with pollfunction */
>> + retval = iio_triggered_buffer_setup(indio_dev, NULL,
>
> devm_()
I disagree. It would change the ordering wrt to the regulator_enable.
Now, obviously it won't actually matter, but it will make the code
less obviously correct and for the small burden of extra unwind
code I'd keep using the non devm version.
>
>> + adc084s021_trigger_handler, NULL);
>> + if (retval) {
>> + dev_err(&spi->dev, "Failed to setup triggered buffer\n");
>> + goto buffer_setup_failed;
>> + }
>> +
>> + retval = iio_device_register(indio_dev);
>> + if (retval) {
>> + dev_err(&spi->dev, "Failed to register IIO device\n");
Hmm. If we were to flesh out some error messages for the few
cases where there is no info provided in iio_device_register we could
probably clean out a fair bit of boiler plate reporting in drivers.
Ah well, one for the future!
>> + goto device_register_failed;
>> + }
>> +
>> + dev_info(&spi->dev, "probed!\n");
>
> no logging please, just outputs clutter
>
>> + return 0;
>> +
>> +device_register_failed:
>> + iio_triggered_buffer_cleanup(indio_dev);
>> +buffer_setup_failed:
>> + regulator_disable(adc->reg);
>> + return retval;
>> +}
>> +
>> +/**
>> + * Unregister ADC IIO device for SPI.
>> + */
>> +static int adc084s021_remove(struct spi_device *spi)
>> +{
>> + struct iio_dev *indio_dev = spi_get_drvdata(spi);
>> + struct adc084s021 *adc = iio_priv(indio_dev);
>> +
>> + iio_device_unregister(indio_dev);
>> + iio_triggered_buffer_cleanup(indio_dev);
>> + regulator_disable(adc->reg);
blank line here preferred (slightly!)
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id adc084s021_of_match[] = {
>> + { .compatible = "ti,adc084s021", },
>> + {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, adc084s021_of_match);
>> +
>> +static const struct spi_device_id adc084s021_id[] = {
>> + { MODULE_NAME, 0},
>> + {}
>> +};
>> +
>> +MODULE_DEVICE_TABLE(spi, adc084s021_id);
>> +
>> +static struct spi_driver adc084s021_driver = {
>> + .driver = {
>> + .name = MODULE_NAME,
>> + .of_match_table = of_match_ptr(adc084s021_of_match),
>> + },
>> + .probe = adc084s021_probe,
>> + .remove = adc084s021_remove,
>> + .id_table = adc084s021_id,
>> +};
>> +
Convention often says to not bother with a blank line here or before
the MODULE_DEVICE_TABLE above. Gives a visual indication that these macros
are being passed the structures.
(really minor point!)
>> +module_spi_driver(adc084s021_driver);
>> +
>> +MODULE_AUTHOR("Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>");
>> +MODULE_DESCRIPTION("Texas Instruments ADC084S021");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_VERSION(DRIVER_VERSION);
>>
>
^ permalink raw reply
* [PATCH v3] spi-imx: Implements handling of the SPI_READY mode flag.
From: Leif Middelschulte @ 2017-04-23 19:19 UTC (permalink / raw)
To: broonie-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Leif Middelschulte
From: Leif Middelschulte <leif.middelschulte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This patch implements consideration of the SPI_READY mode flag as
defined in spi.h. It extends the device tree bindings to support
the values defined by the reference manual for the DRCTL field.
Thus supporting edge-triggered and level-triggered bursts.
Signed-off-by: Leif Middelschulte <Leif.Middelschulte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../devicetree/bindings/spi/fsl-imx-cspi.txt | 7 +++++++
drivers/spi/spi-imx.c | 20 ++++++++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
index 8bc95e2fc47f..31b5b21598ff 100644
--- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
+++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
@@ -23,6 +23,12 @@ See the clock consumer binding,
Obsolete properties:
- fsl,spi-num-chipselects : Contains the number of the chipselect
+Optional properties:
+- fsl,spi-rdy-drctl: Integer, representing the value of DRCTL, the register
+controlling the SPI_READY handling. Note that to enable the DRCTL consideration,
+the SPI_READY mode-flag needs to be set too.
+Valid values are: 0 (disabled), 1 (edge-triggered burst) and 2 (level-triggered burst).
+
Example:
ecspi@70010000 {
@@ -35,4 +41,5 @@ ecspi@70010000 {
<&gpio3 25 0>; /* GPIO3_25 */
dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
dma-names = "rx", "tx";
+ fsl,spi-rdy-drctl = <1>;
};
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 9a7c62f471dc..b402530a7a9a 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -95,6 +95,7 @@ struct spi_imx_data {
unsigned int spi_bus_clk;
unsigned int bytes_per_word;
+ unsigned int spi_drctl;
unsigned int count;
void (*tx)(struct spi_imx_data *);
@@ -246,6 +247,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
#define MX51_ECSPI_CTRL_XCH (1 << 2)
#define MX51_ECSPI_CTRL_SMC (1 << 3)
#define MX51_ECSPI_CTRL_MODE_MASK (0xf << 4)
+#define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16)
#define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8
#define MX51_ECSPI_CTRL_PREDIV_OFFSET 12
#define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18)
@@ -355,6 +357,12 @@ static int mx51_ecspi_config(struct spi_device *spi,
*/
ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
+ /*
+ * Enable SPI_RDY handling (falling edge/level triggered).
+ */
+ if (spi->mode & SPI_READY)
+ ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl);
+
/* set clock speed */
ctrl |= mx51_ecspi_clkdiv(spi_imx, config->speed_hz, &clk);
spi_imx->spi_bus_clk = clk;
@@ -1173,7 +1181,7 @@ static int spi_imx_probe(struct platform_device *pdev)
struct spi_master *master;
struct spi_imx_data *spi_imx;
struct resource *res;
- int i, ret, irq;
+ int i, ret, irq, spi_drctl;
if (!np && !mxc_platform_info) {
dev_err(&pdev->dev, "can't get the platform data\n");
@@ -1181,6 +1189,12 @@ static int spi_imx_probe(struct platform_device *pdev)
}
master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data));
+ ret = of_property_read_u32(np, "fsl,spi-rdy-drctl", &spi_drctl);
+ if ((ret < 0) || (spi_drctl >= 0x3)) {
+ /* '11' is reserved */
+ spi_drctl = 0;
+ }
+
if (!master)
return -ENOMEM;
@@ -1216,7 +1230,9 @@ static int spi_imx_probe(struct platform_device *pdev)
spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message;
spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx))
- spi_imx->bitbang.master->mode_bits |= SPI_LOOP;
+ spi_imx->bitbang.master->mode_bits |= SPI_LOOP | SPI_READY;
+
+ spi_imx->spi_drctl = spi_drctl;
init_completion(&spi_imx->xfer_done);
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH V4 1/9] PM / OPP: Allow OPP table to be used for power-domains
From: Kevin Hilman @ 2017-04-23 22:07 UTC (permalink / raw)
To: Viresh Kumar
Cc: Sudeep Holla, Nishanth Menon, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, Viresh Kumar, Rafael Wysocki,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
linaro-kernel-cunTk1MwBs8s++Sfvej+rw,
rnayak-sgV2jX0FEOL9JmXXK+q4OQ, Stephen Boyd,
lina.iyer-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <20170420095248.GJ5436@vireshk-i7>
Viresh Kumar <viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> writes:
> On 20-04-17, 10:43, Sudeep Holla wrote:
>> Just that the term performance is closely related to frequency, it needs
>> to be explicit on what *exactly* it means. As it stands now,
>> it can be used for OPP as I explain which controls both but as you
>> clarify that's not what it's designed for.
>
> We are talking about active states of a power domain here and
> *performance* is the best word I got.
>
> And yes we can still have
> frequency as a configurable here, just that current platforms don't
> have it.
It's not that your platforms don't have frequency, it's just that it's
hidden by firmware on an M3 in your particular case.
DT is meant to model hardware, and surely what the M3 is managing is
frequency and/or voltage (IOW, an OPP).
The way I see it, the problem you're trying to solve is complicated just
because you don't know the exat freq and/or voltage because they are
hiddent behind the firware, and all you have control over is an index.
What if you drop the introduction of the new domain-performance-state
and just stick with OPPs (and phandles to them), and for cases where you
don't know the exact freq/volage pairs, just use indexes and comment
what they refer to:
operating-points = <
/*
* NOTE: actual frequency and voltages are managed by
* firmware and are hidden from HLOS, so we simply use index
* here to select the OPP
*/
1 1
2 2
3 3
>;
Since selecting the OPP is up to the power-domain driver implementation,
this should be fine, IMO.
This would mean just updating the doc to reflect the "relaxing" of these
fields to reflect indexes in cases where the exact freq/voltages are not
known.
IMO, this would be much simpler, as it avoids adding a new property and
continues to use teriminology that people are already familiar with
around OPPs.
Kevin
--
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 1/5] arm64: renesas: r8a7796: Add external audio clocks
From: Kuninori Morimoto @ 2017-04-23 23:56 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Simon Horman, Magnus Damm, Yoshihiro Shimoda, Rob Herring,
Mark Rutland, linux-renesas-soc, devicetree, linux-arm-kernel
In-Reply-To: <1492779321-23939-2-git-send-email-geert+renesas@glider.be>
Hi Geert
> Add the external audio clocks as zero Hz fixed-frequency clocks.
> Boards that provide these clocks should override them.
>
> Based on commit 623197b90c7aa97c ("arm64: renesas: r8a7795: Sound SSI
> PIO support").
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> arch/arm64/boot/dts/renesas/r8a7796.dtsi | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
> index 2ec1ed5f499165ad..101cd41d693a7ab5 100644
> --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
> @@ -120,6 +120,29 @@
> clock-frequency = <0>;
> };
>
> + /*
> + * The external audio clocks are configured as 0 Hz fixed frequency
> + * clocks by default.
> + * Boards that provide audio clocks should override them.
> + */
> + audio_clk_a: audio_clk_a {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <0>;
> + };
> +
> + audio_clk_b: audio_clk_b {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <0>;
> + };
> +
> + audio_clk_c: audio_clk_c {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <0>;
> + };
> +
> /* External CAN clock - to be overridden by boards that provide it */
> can_clk: can {
> compatible = "fixed-clock";
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v3] ARM: dts: at91: sama5d2: add m_can nodes
From: Wenyou Yang @ 2017-04-24 1:12 UTC (permalink / raw)
To: Nicolas.Ferre, Alexandre Belloni, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Russell King
Cc: devicetree, Wenyou Yang, Oliver Hartkopp, linux-kernel, linux-can,
Quentin Schulz, Wenyou Yang, linux-arm-kernel
Add nodes to support the Controller Area Network(M_CAN) on SAMA5D2.
The version of M_CAN IP core is 3.1.0 (CREL = 0x31040730).
As said in SAMA5D2 datasheet, the CAN clock is recommended to use
frequencies of 20, 40 or 80 MHz. To achieve these frequencies,
PMC GCLK3 must select the UPLLCK(480 MHz) as source clock and
divide by 24, 12, or 6. So, the "assigned-clock-rates" property
has three options: 20000000, 40000000, and 80000000.
The "assigned-clock-parents" property should be referred to utmi
fixedly.
The MSBs [bits 31:16] of the CAN Message RAM for CAN0 and CAN1 are
default configured in 0x00200000. To avoid conflict with SRAM map
for PM, change them to 0x00210000 in the AT91Bootstrap via setting
the CAN Memories Address-based Register(SFR_CAN) of SFR.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Tested-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---
The patch is tested on SAMA5D2 Xplained and based on the patch set,
1. [PATCH v4 1/7] can: m_can: Disabled Interrupt Line 1
http://marc.info/?l=linux-can&m=149165343604033&w=2
Changes in v3:
- Add Tested-by tag.
- Change the number of Rx Rx Buffers, Tx Buffers and Tx Event FIFO
to maximum.
Changes in v2:
- Configures 10 TX Event FIFO elements and 10 TX Buffers/FIFO slots,
because the TXE FIFO is needed to be configured.
- Configure the offset of Message RAM for CAN1 followed from CAN0's.
arch/arm/boot/dts/at91-sama5d2_xplained.dts | 24 +++++++++++++
arch/arm/boot/dts/sama5d2.dtsi | 56 +++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
index 9f7f8a7d8ff9..2f19b08dc226 100644
--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
@@ -257,6 +257,12 @@
status = "okay";
};
+ can0: can@f8054000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_default>;
+ status = "okay";
+ };
+
uart3: serial@fc008000 {
atmel,use-dma-rx;
atmel,use-dma-tx;
@@ -321,6 +327,18 @@
bias-disable;
};
+ pinctrl_can0_default: can0_default {
+ pinmux = <PIN_PC10__CANTX0>,
+ <PIN_PC11__CANRX0>;
+ bias-disable;
+ };
+
+ pinctrl_can1_default: can1_default {
+ pinmux = <PIN_PC26__CANTX1>,
+ <PIN_PC27__CANRX1>;
+ bias-disable;
+ };
+
pinctrl_charger_chglev: charger_chglev {
pinmux = <PIN_PA12__GPIO>;
bias-disable;
@@ -468,6 +486,12 @@
};
};
+
+ can1: can@fc050000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_default>;
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 22332be72140..7e00fa21373e 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -762,6 +762,18 @@
atmel,clk-output-range = <0 83000000>;
};
+ can0_clk: can0_clk {
+ #clock-cells = <0>;
+ reg = <56>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
+ can1_clk: can1_clk {
+ #clock-cells = <0>;
+ reg = <57>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
classd_clk: classd_clk {
#clock-cells = <0>;
reg = <59>;
@@ -890,6 +902,18 @@
#clock-cells = <0>;
reg = <55>;
};
+
+ can0_gclk: can0_gclk {
+ #clock-cells = <0>;
+ reg = <56>;
+ atmel,clk-output-range = <0 80000000>;
+ };
+
+ can1_gclk: can1_gclk {
+ #clock-cells = <0>;
+ reg = <57>;
+ atmel,clk-output-range = <0 80000000>;
+ };
};
};
@@ -1144,6 +1168,22 @@
clocks = <&clk32k>;
};
+ can0: can@f8054000 {
+ compatible = "bosch,m_can";
+ reg = <0xf8054000 0x4000>, <0x210000 0x4000>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>,
+ <64 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-names = "int0", "int1";
+ clocks = <&can0_clk>, <&can0_gclk>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&can0_gclk>;
+ assigned-clock-parents = <&utmi>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
spi1: spi@fc000000 {
compatible = "atmel,at91rm9200-spi";
reg = <0xfc000000 0x100>;
@@ -1305,6 +1345,22 @@
status = "okay";
};
+ can1: can@fc050000 {
+ compatible = "bosch,m_can";
+ reg = <0xfc050000 0x4000>, <0x210000 0x4000>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>,
+ <65 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-names = "int0", "int1";
+ clocks = <&can1_clk>, <&can1_gclk>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&can1_gclk>;
+ assigned-clock-parents = <&utmi>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
chipid@fc069000 {
compatible = "atmel,sama5d2-chipid";
reg = <0xfc069000 0x8>;
--
2.11.0
^ permalink raw reply related
* 12224 devicetree
From: arywhite007-/E1597aS9LQAvxtiuMwx3w @ 2017-04-24 2:10 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: 9062578892.zip --]
[-- Type: application/zip, Size: 1691 bytes --]
^ permalink raw reply
* RE: [PATCH 1/2 v2] dt-bindings: qoriq-clock: Add coreclk
From: Andy Tang @ 2017-04-24 3:14 UTC (permalink / raw)
To: mturquette@baylibre.com, sboyd@codeaurora.org
Cc: robh+dt@kernel.org, mark.rutland@arm.com,
linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Scott Wood
In-Reply-To: <DB6PR0402MB283701D478A1678D28894C77F30A0@DB6PR0402MB2837.eurprd04.prod.outlook.com>
Does anyone give me a clue why this patch set can't be responded after so long time?
Thanks,
Andy
-----Original Message-----
From: Andy Tang
Sent: Monday, April 17, 2017 9:37 AM
To: 'mturquette@baylibre.com' <mturquette@baylibre.com>; 'sboyd@codeaurora.org' <sboyd@codeaurora.org>
Cc: 'robh+dt@kernel.org' <robh+dt@kernel.org>; 'mark.rutland@arm.com' <mark.rutland@arm.com>; 'linux-clk@vger.kernel.org' <linux-clk@vger.kernel.org>; 'devicetree@vger.kernel.org' <devicetree@vger.kernel.org>; 'linux-kernel@vger.kernel.org' <linux-kernel@vger.kernel.org>; 'linux-arm-kernel@lists.infradead.org' <linux-arm-kernel@lists.infradead.org>; 'Scott Wood' <oss@buserror.net>
Subject: RE: [PATCH 1/2 v2] dt-bindings: qoriq-clock: Add coreclk
Hi Stephen and Michael,
This patch set has been pending for more than two months since it was first sent.
I have not received any response from you until now.
Could you give some comments on it?
Regards,
Andy
-----Original Message-----
From: Andy Tang
Sent: Wednesday, April 05, 2017 2:16 PM
To: mturquette@baylibre.com; sboyd@codeaurora.org
Cc: robh+dt@kernel.org; mark.rutland@arm.com; linux-clk@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Scott Wood <oss@buserror.net>
Subject: RE: [PATCH 1/2 v2] dt-bindings: qoriq-clock: Add coreclk
Hello
Do you have any comments on this patch set which was acked by Rob?
Regards,
Andy
> -----Original Message-----
> From: Yuantian Tang [mailto:andy.tang@nxp.com]
> Sent: Monday, March 20, 2017 10:37 AM
> To: mturquette@baylibre.com
> Cc: sboyd@codeaurora.org; robh+dt@kernel.org; mark.rutland@arm.com;
> linux-clk@vger.kernel.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; Scott
> Wood <oss@buserror.net>; Andy Tang <andy.tang@nxp.com>
> Subject: [PATCH 1/2 v2] dt-bindings: qoriq-clock: Add coreclk
>
> From: Scott Wood <oss@buserror.net>
>
> ls1012a has separate input root clocks for core PLLs versus the
> platform PLL, with the latter described as sysclk in the hw docs.
> Update the qoriq-clock binding to allow a second input clock, named
> "coreclk". If present, this clock will be used for the core PLLs.
>
> Signed-off-by: Scott Wood <oss@buserror.net>
> Signed-off-by: Tang Yuantian <andy.tang@nxp.com>
> Acked-by: Rob Herring <robh@kernel.org>
> ---
> v2:
> -- change the author to Scott
> Documentation/devicetree/bindings/clock/qoriq-clock.txt | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> index aa3526f..119cafd 100644
> --- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> +++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
> @@ -56,6 +56,11 @@ Optional properties:
> - clocks: If clock-frequency is not specified, sysclk may be provided
> as an input clock. Either clock-frequency or clocks must be
> provided.
> + A second input clock, called "coreclk", may be provided if
> + core PLLs are based on a different input clock from the
> + platform PLL.
> +- clock-names: Required if a coreclk is present. Valid names are
> + "sysclk" and "coreclk".
>
> 2. Clock Provider
>
> @@ -72,6 +77,7 @@ second cell is the clock index for the specified type.
> 2 hwaccel index (n in CLKCGnHWACSR)
> 3 fman 0 for fm1, 1 for fm2
> 4 platform pll 0=pll, 1=pll/2, 2=pll/3, 3=pll/4
> + 5 coreclk must be 0
>
> 3. Example
>
> --
> 2.1.0.27.g96db324
^ permalink raw reply
* [PATCH 0/3] of: fix overlay modification of const variable
From: frowand.list @ 2017-04-24 5:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel
From: Frank Rowand <frank.rowand@sony.com>
When adjusting overlay phandles to apply to the live device tree, can
not modify the property value because it is type const.
This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *. As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.
[1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
Patch 1 fixes the const variable problem.
Patches 2 and 3 are minor fixups for issues that became visible
while implementing patch 1.
Frank Rowand (3):
of: overlay_adjust_phandles() - do not modify const field
of: make __of_attach_node() static
of: detect invalid phandle in overlay
drivers/of/base.c | 4 ++--
drivers/of/dynamic.c | 30 ++++++++++++++++++++++-------
drivers/of/of_private.h | 4 +++-
drivers/of/overlay.c | 4 ++++
drivers/of/resolver.c | 51 ++++++++++++++++++++++++++++++-------------------
5 files changed, 63 insertions(+), 30 deletions(-)
--
Frank Rowand <frank.rowand@sony.com>
^ permalink raw reply
* [PATCH 1/3] of: overlay_adjust_phandles() - do not modify const field
From: frowand.list @ 2017-04-24 5:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel
In-Reply-To: <1493011204-27635-1-git-send-email-frowand.list@gmail.com>
From: Frank Rowand <frank.rowand@sony.com>
When adjusting overlay phandles to apply to the live device tree, can
not modify the property value because it is type const.
This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *. As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.
[1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
drivers/of/base.c | 4 ++--
drivers/of/dynamic.c | 28 +++++++++++++++++++++------
drivers/of/of_private.h | 3 +++
drivers/of/resolver.c | 51 ++++++++++++++++++++++++++++++-------------------
4 files changed, 58 insertions(+), 28 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d7c4629a3a2d..b41650fd0fcf 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -220,8 +220,8 @@ void __init of_core_init(void)
proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
}
-static struct property *__of_find_property(const struct device_node *np,
- const char *name, int *lenp)
+struct property *__of_find_property(const struct device_node *np,
+ const char *name, int *lenp)
{
struct property *pp;
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 888fdbc09992..44963b4e7235 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -354,17 +354,17 @@ void of_node_release(struct kobject *kobj)
}
/**
- * __of_prop_dup - Copy a property dynamically.
+ * __of_prop_alloc - Create a property dynamically.
* @prop: Property to copy
* @allocflags: Allocation flags (typically pass GFP_KERNEL)
*
- * Copy a property by dynamically allocating the memory of both the
+ * Create a property by dynamically allocating the memory of both the
* property structure and the property name & contents. The property's
* flags have the OF_DYNAMIC bit set so that we can differentiate between
* dynamically allocated properties and not.
* Returns the newly allocated property or NULL on out of memory error.
*/
-struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
+struct property *__of_prop_alloc(char *name, void *value, int len, gfp_t allocflags)
{
struct property *new;
@@ -378,9 +378,9 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
* of zero bytes. We do this to work around the use
* of of_get_property() calls on boolean values.
*/
- new->name = kstrdup(prop->name, allocflags);
- new->value = kmemdup(prop->value, prop->length, allocflags);
- new->length = prop->length;
+ new->name = kstrdup(name, allocflags);
+ new->value = kmemdup(value, len, allocflags);
+ new->length = len;
if (!new->name || !new->value)
goto err_free;
@@ -397,6 +397,22 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
}
/**
+ * __of_prop_dup - Copy a property dynamically.
+ * @prop: Property to copy
+ * @allocflags: Allocation flags (typically pass GFP_KERNEL)
+ *
+ * Copy a property by dynamically allocating the memory of both the
+ * property structure and the property name & contents. The property's
+ * flags have the OF_DYNAMIC bit set so that we can differentiate between
+ * dynamically allocated properties and not.
+ * Returns the newly allocated property or NULL on out of memory error.
+ */
+struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
+{
+ return __of_prop_alloc(prop->name, prop->value, prop->length, allocflags);
+}
+
+/**
* __of_node_dup() - Duplicate or create an empty device node dynamically.
* @fmt: Format string (plus vargs) for new full name of the device node
*
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 18bbb4517e25..554394c96569 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -62,6 +62,7 @@ static inline int of_property_notify(int action, struct device_node *np,
* without taking node references, so you either have to
* own the devtree lock or work on detached trees only.
*/
+struct property *__of_prop_alloc(char *name, void *value, int len, gfp_t allocflags);
struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
__printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...);
@@ -70,6 +71,8 @@ extern const void *__of_get_property(const struct device_node *np,
extern int __of_add_property(struct device_node *np, struct property *prop);
extern int __of_add_property_sysfs(struct device_node *np,
struct property *prop);
+extern struct property *__of_find_property(const struct device_node *np,
+ const char *name, int *lenp);
extern int __of_remove_property(struct device_node *np, struct property *prop);
extern void __of_remove_property_sysfs(struct device_node *np,
struct property *prop);
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 7ae9863cb0a4..a2d5b8f0b7bf 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -20,6 +20,8 @@
#include <linux/errno.h>
#include <linux/slab.h>
+#include "of_private.h"
+
/* illegal phandle value (set when unresolved) */
#define OF_PHANDLE_ILLEGAL 0xdeadbeef
@@ -67,36 +69,43 @@ static phandle live_tree_max_phandle(void)
return phandle;
}
-static void adjust_overlay_phandles(struct device_node *overlay,
+static int adjust_overlay_phandles(struct device_node *overlay,
int phandle_delta)
{
struct device_node *child;
+ struct property *newprop;
struct property *prop;
phandle phandle;
+ int ret;
- /* adjust node's phandle in node */
- if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
- overlay->phandle += phandle_delta;
-
- /* copy adjusted phandle into *phandle properties */
- for_each_property_of_node(overlay, prop) {
+ if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL) {
- if (of_prop_cmp(prop->name, "phandle") &&
- of_prop_cmp(prop->name, "linux,phandle"))
- continue;
-
- if (prop->length < 4)
- continue;
+ overlay->phandle += phandle_delta;
- phandle = be32_to_cpup(prop->value);
- if (phandle == OF_PHANDLE_ILLEGAL)
- continue;
+ phandle = cpu_to_be32(overlay->phandle);
+
+ prop = __of_find_property(overlay, "phandle", NULL);
+ newprop = __of_prop_alloc(prop->name, &phandle, sizeof(phandle),
+ GFP_KERNEL);
+ if (!newprop)
+ return -ENOMEM;
+ __of_update_property(overlay, newprop, &prop);
+
+ prop = __of_find_property(overlay, "linux,phandle", NULL);
+ newprop = __of_prop_alloc(prop->name, &phandle, sizeof(phandle),
+ GFP_KERNEL);
+ if (!newprop)
+ return -ENOMEM;
+ __of_update_property(overlay, newprop, &prop);
+ }
- *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
+ for_each_child_of_node(overlay, child) {
+ ret = adjust_overlay_phandles(child, phandle_delta);
+ if (ret)
+ return ret;
}
- for_each_child_of_node(overlay, child)
- adjust_overlay_phandles(child, phandle_delta);
+ return 0;
}
static int update_usages_of_a_phandle_reference(struct device_node *overlay,
@@ -306,7 +315,9 @@ int of_resolve_phandles(struct device_node *overlay)
}
phandle_delta = live_tree_max_phandle() + 1;
- adjust_overlay_phandles(overlay, phandle_delta);
+ err = adjust_overlay_phandles(overlay, phandle_delta);
+ if (err)
+ goto out;
for_each_child_of_node(overlay, local_fixups)
if (!of_node_cmp(local_fixups->name, "__local_fixups__"))
--
Frank Rowand <frank.rowand@sony.com>
^ permalink raw reply related
* [PATCH 2/3] of: make __of_attach_node() static
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-24 5:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493011204-27635-1-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
__of_attach_node() is not used outside of drivers/of/dynamic.c. Make
it static and remove it from drivers/of/of_private.h.
Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
drivers/of/dynamic.c | 2 +-
drivers/of/of_private.h | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 44963b4e7235..9dcadd704aee 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -216,7 +216,7 @@ int of_property_notify(int action, struct device_node *np,
return of_reconfig_notify(action, &pr);
}
-void __of_attach_node(struct device_node *np)
+static void __of_attach_node(struct device_node *np)
{
const __be32 *phandle;
int sz;
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 554394c96569..f4f6793d2f04 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -81,7 +81,6 @@ extern int __of_update_property(struct device_node *np,
extern void __of_update_property_sysfs(struct device_node *np,
struct property *newprop, struct property *oldprop);
-extern void __of_attach_node(struct device_node *np);
extern int __of_attach_node_sysfs(struct device_node *np);
extern void __of_detach_node(struct device_node *np);
extern void __of_detach_node_sysfs(struct device_node *np);
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/3] of: detect invalid phandle in overlay
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-24 5:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493011204-27635-1-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
Overlays are not allowed to modify phandle values of previously existing
nodes because there is no information available to allow fixup up of
properties that use the previously existing phandle.
Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
drivers/of/overlay.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 7827786718d8..c0e4ee1cd1ba 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -132,6 +132,10 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov,
/* NOTE: Multiple mods of created nodes not supported */
tchild = of_get_child_by_name(target, cname);
if (tchild != NULL) {
+ /* new overlay phandle value conflicts with existing value */
+ if (child->phandle)
+ return -EINVAL;
+
/* apply overlay recursively */
ret = of_overlay_apply_one(ov, tchild, child);
of_node_put(tchild);
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 0/2] of: Add unit tests for applying overlays
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-24 5:43 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A, Michal Marek
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-kbuild-u79uwXL29TY76Z2rM5mHXA
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
Existing overlay unit tests examine individual pieces of the overlay
code. The new tests target the entire process of applying an overlay.
Frank Rowand (2):
of: add support of dtc compiler flags for device tree overlays
of: Add unit tests for applying overlays.
drivers/of/fdt.c | 45 +++++
drivers/of/of_private.h | 2 +
drivers/of/unittest-data/Makefile | 17 +-
drivers/of/unittest-data/ot.dts | 53 ++++++
drivers/of/unittest-data/ot_bad_phandle.dts | 20 +++
drivers/of/unittest-data/ot_base.dts | 71 ++++++++
drivers/of/unittest.c | 264 ++++++++++++++++++++++++++++
scripts/Makefile.lib | 2 +
8 files changed, 471 insertions(+), 3 deletions(-)
create mode 100644 drivers/of/unittest-data/ot.dts
create mode 100644 drivers/of/unittest-data/ot_bad_phandle.dts
create mode 100644 drivers/of/unittest-data/ot_base.dts
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/2] of: add support of dtc compiler flags for device tree overlays
From: frowand.list @ 2017-04-24 5:43 UTC (permalink / raw)
To: Rob Herring, stephen.boyd, Michal Marek
Cc: devicetree, linux-kernel, linux-kbuild
In-Reply-To: <1493012595-696-1-git-send-email-frowand.list@gmail.com>
From: Frank Rowand <frank.rowand@sony.com>
The dtc compiler version that adds initial support was available
in 4.11-rc1. Add the ability to set the dtc compiler flags needed
by overlays.
Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
scripts/Makefile.lib | 2 ++
1 file changed, 2 insertions(+)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a07f9014944..0bbec480d323 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -283,6 +283,8 @@ ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),)
DTC_FLAGS += -Wno-unit_address_vs_reg
endif
+DTC_FLAGS += $(DTC_FLAGS_$(basetarget))
+
# Generate an assembly file to wrap the output of the device tree compiler
quiet_cmd_dt_S_dtb= DTB $@
cmd_dt_S_dtb= \
--
Frank Rowand <frank.rowand@sony.com>
^ permalink raw reply related
* [PATCH 2/2] of: Add unit tests for applying overlays.
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-24 5:43 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A, Michal Marek
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-kbuild-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493012595-696-1-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
Existing overlay unit tests examine individual pieces of the overlay
code. The new tests target the entire process of applying an overlay.
Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
There are checkpatch warnings. I have reviewed them and feel they
can be ignored.
drivers/of/fdt.c | 45 +++++
drivers/of/of_private.h | 2 +
drivers/of/unittest-data/Makefile | 17 +-
drivers/of/unittest-data/ot.dts | 53 ++++++
drivers/of/unittest-data/ot_bad_phandle.dts | 20 +++
drivers/of/unittest-data/ot_base.dts | 71 ++++++++
drivers/of/unittest.c | 264 ++++++++++++++++++++++++++++
7 files changed, 469 insertions(+), 3 deletions(-)
create mode 100644 drivers/of/unittest-data/ot.dts
create mode 100644 drivers/of/unittest-data/ot_bad_phandle.dts
create mode 100644 drivers/of/unittest-data/ot_base.dts
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index e5ce4b59e162..54120ab8f322 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -31,6 +31,8 @@
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include <asm/page.h>
+#include "of_private.h"
+
/*
* of_fdt_limit_memory - limit the number of regions in the /memory node
* @limit: maximum entries
@@ -1256,11 +1258,54 @@ bool __init early_init_dt_scan(void *params)
*/
void __init unflatten_device_tree(void)
{
+#ifdef CONFIG_OF_UNITTEST
+ extern uint8_t __dtb_ot_base_begin[];
+ extern uint8_t __dtb_ot_base_end[];
+ struct device_node *ot_base_root;
+ void *ot_base;
+ u32 data_size;
+ u32 size;
+#endif
+
__unflatten_device_tree(initial_boot_params, NULL, &of_root,
early_init_dt_alloc_memory_arch, false);
/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
of_alias_scan(early_init_dt_alloc_memory_arch);
+
+#ifdef CONFIG_OF_UNITTEST
+ /*
+ * Base device tree for the overlay unittest.
+ * Do as much as possible the same way as done for the normal FDT.
+ * Have to stop before resolving phandles, because that uses kmalloc.
+ */
+
+ data_size = __dtb_ot_base_end - __dtb_ot_base_begin;
+ if (!data_size) {
+ pr_err("No __dtb_ot_base_begin to attach\n");
+ return;
+ }
+
+ size = fdt_totalsize(__dtb_ot_base_begin);
+ if (size != data_size) {
+ pr_err("__dtb_ot_base_begin header totalsize != actual size");
+ return;
+ }
+
+ ot_base = early_init_dt_alloc_memory_arch(size,
+ roundup_pow_of_two(FDT_V17_SIZE));
+ if (!ot_base) {
+ pr_err("alloc of ot_base failed");
+ return;
+ }
+
+ memcpy(ot_base, __dtb_ot_base_begin, size);
+
+ __unflatten_device_tree(ot_base, NULL, &ot_base_root,
+ early_init_dt_alloc_memory_arch, true);
+
+ unittest_set_ot_base_root(ot_base_root);
+#endif
}
/**
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index f4f6793d2f04..02d54da078ac 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -55,6 +55,8 @@ static inline int of_property_notify(int action, struct device_node *np,
}
#endif /* CONFIG_OF_DYNAMIC */
+extern void unittest_set_ot_base_root(struct device_node *dn);
+
/**
* General utilities for working with live trees.
*
diff --git a/drivers/of/unittest-data/Makefile b/drivers/of/unittest-data/Makefile
index 1ac5cc01d627..6879befe29d2 100644
--- a/drivers/of/unittest-data/Makefile
+++ b/drivers/of/unittest-data/Makefile
@@ -1,7 +1,18 @@
obj-y += testcases.dtb.o
+obj-y += ot.dtb.o
+obj-y += ot_bad_phandle.dtb.o
+obj-y += ot_base.dtb.o
targets += testcases.dtb testcases.dtb.S
+targets += ot.dtb ot.dtb.S
+targets += ot_bad_phandle.dtb ot_bad_phandle.dtb.S
+targets += ot_base.dtb ot_base.dtb.S
-.SECONDARY: \
- $(obj)/testcases.dtb.S \
- $(obj)/testcases.dtb
+.PRECIOUS: \
+ $(obj)/%.dtb.S \
+ $(obj)/%.dtb
+
+# enable creation of __symbols__ node
+DTC_FLAGS_ot := -@
+DTC_FLAGS_ot_base := -@
+DTC_FLAGS_ot_bad_phandle := -@
diff --git a/drivers/of/unittest-data/ot.dts b/drivers/of/unittest-data/ot.dts
new file mode 100644
index 000000000000..37e105622b7a
--- /dev/null
+++ b/drivers/of/unittest-data/ot.dts
@@ -0,0 +1,53 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+
+ fragment@0 {
+ target = <&electric_1>;
+
+ __overlay__ {
+ status = "ok";
+
+ hvac_2: hvac_large_1 {
+ compatible = "ot,hvac-large";
+ heat-range = < 40 75 >;
+ cool-range = < 65 80 >;
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&rides_1>;
+
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "ok";
+
+ ride@200 {
+ compatible = "ot,ferris-wheel";
+ reg = < 0x00000200 0x100 >;
+ hvac-provider = < &hvac_2 >;
+ hvac-thermostat = < 27 32 > ;
+ hvac-zones = < 12 5 >;
+ hvac-zone-names = "operator", "snack-bar";
+ spin-controller = < &spin_ctrl_1 3 >;
+ spin-rph = < 30 >;
+ gondolas = < 16 >;
+ gondola-capacity = < 6 >;
+ };
+ };
+ };
+
+ fragment@2 {
+ target = <&lights_2>;
+
+ __overlay__ {
+ status = "ok";
+ color = "purple", "white", "red", "green";
+ rate = < 3 256 >;
+ };
+ };
+
+};
diff --git a/drivers/of/unittest-data/ot_bad_phandle.dts b/drivers/of/unittest-data/ot_bad_phandle.dts
new file mode 100644
index 000000000000..234d5f1dcfe4
--- /dev/null
+++ b/drivers/of/unittest-data/ot_bad_phandle.dts
@@ -0,0 +1,20 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+
+ fragment@0 {
+ target = <&electric_1>;
+
+ __overlay__ {
+
+ // This label should cause an error when the overlay
+ // is applied. There is already a phandle value
+ // in the base tree for motor_1.
+ spin_ctrl_1_conflict: motor_1 {
+ accelerate = < 3 >;
+ decelerate = < 5 >;
+ };
+ };
+ };
+};
diff --git a/drivers/of/unittest-data/ot_base.dts b/drivers/of/unittest-data/ot_base.dts
new file mode 100644
index 000000000000..0a4fbe598b02
--- /dev/null
+++ b/drivers/of/unittest-data/ot_base.dts
@@ -0,0 +1,71 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ testcase-data-2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ electric_1: substation@100 {
+ compatible = "ot,big-volts-control";
+ reg = < 0x00000100 0x100 >;
+ status = "disabled";
+
+ hvac_1: hvac_medium_1 {
+ compatible = "ot,hvac-medium";
+ heat-range = < 50 75 >;
+ cool-range = < 60 80 >;
+ };
+
+ spin_ctrl_1: motor_1 {
+ compatible = "ot,ferris-wheel-motor";
+ spin = "clockwise";
+ };
+
+ spin_ctrl_2: motor_8 {
+ compatible = "ot,roller-coaster-motor";
+ };
+ };
+
+ rides_1: fairway_1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ot,rides";
+ status = "disabled";
+ orientation = < 127 >;
+
+ ride@100 {
+ compatible = "ot,roller-coaster";
+ reg = < 0x00000100 0x100 >;
+ hvac-provider = < &hvac_1 >;
+ hvac-thermostat = < 29 > ;
+ hvac-zones = < 14 >;
+ hvac-zone-names = "operator";
+ spin-controller = < &spin_ctrl_2 5 &spin_ctrl_2 7 >;
+ spin-controller-names = "track_1", "track_2";
+ queues = < 2 >;
+ };
+ };
+
+ lights_1: lights@30000 {
+ compatible = "ot,work-lights";
+ reg = < 0x00030000 0x1000 >;
+ status = "disabled";
+ };
+
+ lights_2: lights@40000 {
+ compatible = "ot,show-lights";
+ reg = < 0x00040000 0x1000 >;
+ status = "disabled";
+ rate = < 13 138 >;
+ };
+
+ retail_1: vending@50000 {
+ reg = < 0x00050000 0x1000 >;
+ compatible = "ot,tickets";
+ status = "disabled";
+ };
+
+ };
+};
+
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 62db55b97c10..599eb10e9b40 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/hashtable.h>
+#include <linux/libfdt.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
@@ -42,6 +43,13 @@
failed; \
})
+static struct device_node *ot_base_root;
+
+void unittest_set_ot_base_root(struct device_node *dn)
+{
+ ot_base_root = dn;
+}
+
static void __init of_unittest_find_node_by_name(void)
{
struct device_node *np;
@@ -1925,6 +1933,259 @@ static void __init of_unittest_overlay(void)
static inline void __init of_unittest_overlay(void) { }
#endif
+#define OVERLAY_INFO_EXTERN(name) \
+ extern uint8_t __dtb_##name##_begin[]; \
+ extern uint8_t __dtb_##name##_end[]
+
+#define OVERLAY_INFO(name, expected) \
+{ .dtb_begin = __dtb_##name##_begin, \
+ .dtb_end = __dtb_##name##_end, \
+ .expected_result = expected, \
+}
+
+struct overlay_info {
+ uint8_t *dtb_begin;
+ uint8_t *dtb_end;
+ void *data;
+ struct device_node *np_overlay;
+ int expected_result;
+ int overlay_id;
+};
+
+OVERLAY_INFO_EXTERN(ot);
+OVERLAY_INFO_EXTERN(ot_bad_phandle);
+
+struct overlay_info overlays[] = {
+ OVERLAY_INFO(ot, 0),
+ OVERLAY_INFO(ot_bad_phandle, -EINVAL),
+ {}
+};
+
+#ifdef CONFIG_OF_OVERLAY
+/*
+ * The purpose of of_unittest_overlay_test_data_add is to add an
+ * overlay in the normal fashion. This is a test of the whole
+ * picture, instead of testing individual elements.
+ *
+ * A secondary purpose is to be able to verify that the contents of
+ * /proc/device-tree/ contains the updated structure and values from
+ * the overlay. That must be verified separately in user space.
+ *
+ * Return 0 on unexpected error.
+ */
+static int __init overlay_test_data_add(int onum)
+{
+ /*
+ * __dtb_ot_begin[] and __dtb_ot_end[] are
+ * created by cmd_dt_S_dtb in scripts/Makefile.lib
+ */
+ struct overlay_info *info;
+ int k;
+ int ret;
+ u32 size;
+ u32 size_from_header;
+
+ for (k = 0, info = overlays; info; info++, k++) {
+ if (k == onum)
+ break;
+ }
+ if (onum > k)
+ return 0;
+
+ size = info->dtb_end - info->dtb_begin;
+ if (!size) {
+ pr_err("no overlay to attach, %d\n", onum);
+ ret = 0;
+ }
+
+ size_from_header = fdt_totalsize(info->dtb_begin);
+ if (size_from_header != size) {
+ pr_err("overlay header totalsize != actual size, %d", onum);
+ return 0;
+ }
+
+ /*
+ * Must create permanent copy of FDT because of_fdt_unflatten_tree()
+ * will create pointers to the passed in FDT in the EDT.
+ */
+ info->data = kmemdup(info->dtb_begin, size, GFP_KERNEL);
+ if (!info->data) {
+ pr_err("unable to allocate memory for data, %d\n", onum);
+ return 0;
+ }
+
+ of_fdt_unflatten_tree(info->data, NULL, &info->np_overlay);
+ if (!info->np_overlay) {
+ pr_err("unable to unflatten overlay, %d\n", onum);
+ ret = 0;
+ goto out_free_data;
+ }
+ of_node_set_flag(info->np_overlay, OF_DETACHED);
+
+ ret = of_resolve_phandles(info->np_overlay);
+ if (ret) {
+ pr_err("resolve ot phandles (ret=%d), %d\n", ret, onum);
+ goto out_free_np_overlay;
+ }
+
+ ret = of_overlay_create(info->np_overlay);
+ if (ret < 0) {
+ pr_err("of_overlay_create() (ret=%d), %d\n", ret, onum);
+ goto out_free_np_overlay;
+ } else {
+ info->overlay_id = ret;
+ ret = 0;
+ }
+
+ pr_debug("__dtb_ot_begin applied, overlay id %d\n", ret);
+
+ goto out;
+
+out_free_np_overlay:
+ /*
+ * info->np_overlay is the unflattened device tree
+ * It has not been spliced into the live tree.
+ */
+
+ /* todo: function to free unflattened device tree */
+
+out_free_data:
+ kfree(info->data);
+
+out:
+ return (ret == info->expected_result);
+}
+
+/*
+ * The purpose of of_unittest_overlay_high_level is to add an overlay
+ * in the normal fashion. This is a test of the whole picture,
+ * instead of individual elements.
+ *
+ * The first part of the function is _not_ normal overlay usage; it is
+ * finishing splicing the base overlay device tree into the live tree.
+ */
+static __init void of_unittest_overlay_high_level(void)
+{
+ struct device_node *last_sibling;
+ struct device_node *np;
+ struct device_node *of_symbols;
+ struct device_node *ot_base_symbols;
+ struct device_node **pprev;
+ struct property *prop;
+ int ret;
+
+ if (!ot_base_root) {
+ unittest(0, "ot_base_root not initialized\n");
+ return;
+ }
+
+ /*
+ * Could not fixup phandles in unflatten_device_tree() because
+ * kmalloc() was not yet available.
+ */
+ of_resolve_phandles(ot_base_root);
+
+ /*
+ * do not allow ot_base to duplicate any node already in tree,
+ * this greatly simplifies the code
+ */
+
+
+ /* remove ot_base_root node "__local_fixups" */
+ pprev = &ot_base_root->child;
+ for (np = ot_base_root->child; np; np = np->sibling) {
+ if (!of_node_cmp(np->name, "__local_fixups__")) {
+ *pprev = np->sibling;
+ break;
+ }
+ pprev = &np->sibling;
+ }
+
+
+ /* remove ot_base_root node "__symbols__" if in live tree*/
+ of_symbols = of_get_child_by_name(of_root, "__symbols__");
+ if (of_symbols) {
+ /* will have to graft properties from node into live tree */
+ pprev = &ot_base_root->child;
+ for (np = ot_base_root->child; np; np = np->sibling) {
+ if (!of_node_cmp(np->name, "__symbols__")) {
+ ot_base_symbols = np;
+ *pprev = np->sibling;
+ break;
+ }
+ pprev = &np->sibling;
+ }
+ }
+
+ for (np = ot_base_root->child; np; np = np->sibling) {
+ if (of_get_child_by_name(of_root, np->name)) {
+ unittest(0, "illegal node name in ot_base %s",
+ np->name);
+ return;
+ }
+ }
+
+ /*
+ * __dtb_ot_base_begin is not allowed to have root properties,
+ * so only need to splice nodes into main device tree.
+ *
+ * root node of *ot_base_root will not be freed, it is lost
+ * memory.
+ */
+
+ for (np = ot_base_root->child; np; np = np->sibling)
+ np->parent = of_root;
+
+ mutex_lock(&of_mutex);
+
+ for (np = of_root->child; np; np = np->sibling)
+ last_sibling = np;
+
+ if (last_sibling)
+ last_sibling->sibling = ot_base_root->child;
+ else
+ of_root->child = ot_base_root->child;
+
+ for_each_of_allnodes_from(ot_base_root, np)
+ __of_attach_node_sysfs(np);
+
+ if (of_symbols) {
+ for_each_property_of_node(ot_base_symbols, prop) {
+ ret = __of_add_property(of_symbols, prop);
+ if (ret) {
+ unittest(0,
+ "duplicate property '%s' in ot_base node __symbols__",
+ prop->name);
+ return;
+ }
+ ret = __of_add_property_sysfs(of_symbols, prop);
+ if (ret) {
+ unittest(0,
+ "unable to add property '%s' in ot_base node __symbols__ to sysfs",
+ prop->name);
+ return;
+ }
+ }
+ }
+
+ mutex_unlock(&of_mutex);
+
+
+ /* now do the normal overlay usage test */
+
+ unittest(overlay_test_data_add(0),
+ "Adding overlay __dtb_ot_begin failed\n");
+
+ unittest(overlay_test_data_add(1),
+ "Adding overlay phandle conflict failed\n");
+}
+
+#else
+
+static inline __init void of_unittest_overlay_high_level(void) {}
+
+#endif
+
static int __init of_unittest(void)
{
struct device_node *np;
@@ -1962,6 +2223,9 @@ static int __init of_unittest(void)
/* Double check linkage after removing testcase data */
of_unittest_check_tree_linkage();
+
+ of_unittest_overlay_high_level();
+
pr_info("end of unittest - %i passed, %i failed\n",
unittest_results.passed, unittest_results.failed);
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v2 0/9] drm/sun4i: Support multiple display pipelines
From: Maxime Ripard @ 2017-04-24 5:51 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: David Airlie, Rob Herring, Mark Rutland,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20170421083857.29636-1-wens-jdAy2FN1RRM@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2338 bytes --]
On Fri, Apr 21, 2017 at 04:38:48PM +0800, Chen-Yu Tsai wrote:
> Hi,
>
> This is v2 of the series previously named "drm/sun4i: Support two
> display pipelines". As the name change suggests, the driver now
> supports any number of pipelines, though the hardware only has
> 2 or 3.
>
> Changes since v1:
>
> - Add component endpoint ID numbering scheme to device tree binding.
>
> - Use lists to keep references to registered backends and tcons.
>
> - Save pointer to device node for backends.
>
> - Traverse the device tree of_graph starting from the tcons, going
> up towards the inputs, and matching the device nodes with the
> device nodes of registered backends, to find the one linked with
> the tcon the search started from.
>
> - Copy the ID for the tcon from its upstream backend, instead of
> trying, and possibly failing, to figure it out from the device
> tree.
>
> - Split out hunk dropping trailing 0 from a backend error message.
>
> Patch 1 adds the component endpoint ID numbering scheme to the
> device tree binding. New in v2.
>
> Patch 2 adds lists to track registered display backends and TCONs,
> instead of just one pointer per component type. Previously added
> arrays of pointers in v1.
>
> Patch 3 drops the trailing 0 from one of the backend's bind error
> messages. This was previously part of the patch "drm/sun4i: Support
> two display pipelines".
>
> Patch 4 adds a function to fetch a backend's ID from the device tree.
> Unchanged.
>
> Patch 5 adds a device node field to the backend data structure and
> saves a reference to the underlying device node of the backend.
> New in v2.
>
> Patch 6 makes the tcon driver find its upstream backend by traversing
> the of_graph and matching device nodes against the device nodes of
> registered backends.
> New in v2.
>
> Patch 7 makes the tcon driver use the ID from its associated backend.
> New in v2. This is not immediately used in this series, but will be
> used in similar fashion for downstream encoders to figure out IDs and
> muxing
>
> Patch 8 adds device nodes for sun6i's second display pipeline.
> Unchanged.
>
> Patch 9 enables sun6i's tcon0 by default.
> Unchanged.
Applied everything, thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
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