* [PATCH] ARM: imx: introduce imx_l2c310_write_sec
From: Philippe Ombredanne @ 2017-12-29 12:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1514453750-15479-1-git-send-email-peng.fan@nxp.com>
Dear Peng,
On Thu, Dec 28, 2017 at 10:35 AM, Peng Fan <peng.fan@nxp.com> wrote:
> Some PL310 registers could only be wrote in secure world, so
> introduce imx_l2c310_write_sec to support Linux running in
> non-secure world.
<snip>
> --- /dev/null
> +++ b/include/soc/imx/imx_sip_smc.h
> @@ -0,0 +1,23 @@
> +/*
> + * Copyright 2017 NXP
> + *
> + * 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.
> + */
Do you mind using a simpler SPDX identifier instead of this longer
legalese boilerplate? This is documented in Thomas doc patches.
If you could also spread the word in your team that would be much welcomed.
Thanks!
--
Cordially
Philippe Ombredanne
^ permalink raw reply
* [GIT PULL] ARM: dts: uniphier: UniPhier DT updates for v4.16
From: Masahiro Yamada @ 2017-12-29 13:32 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd, Olof,
Here are UniPhier DT (32bit) updates for the v4.16 merge window.
Please pull!
The following changes since commit 50c4c4e268a2d7a3e58ebb698ac74da0de40ae36:
Linux 4.15-rc3 (2017-12-10 17:56:26 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git
tags/uniphier-dt-v4.16
for you to fetch changes up to 6fa9b0255099fcd289f7e3857714532843044c76:
ARM: dts: uniphier: add has-transaction-translator property to usb
node for LD4, sLD8 and Pro4 (2017-12-27 23:59:37 +0900)
----------------------------------------------------------------
UniPhier ARM SoC DT updates for v4.16
- clean up gpios properties by macro
- add efuse nodes
- add has-transaction-translator property to generic-ehci nodes
----------------------------------------------------------------
Keiji Hayashibara (1):
ARM: dts: uniphier: add efuse node for UniPhier 32bit SoC
Kunihiko Hayashi (1):
ARM: dts: uniphier: add has-transaction-translator property to
usb node for LD4, sLD8 and Pro4
Masahiro Yamada (1):
ARM: dts: uniphier: use macros in dt-bindings header
arch/arm/boot/dts/uniphier-ld4-ref.dts | 2 +-
arch/arm/boot/dts/uniphier-ld4.dtsi | 23 +++++++++++++++++
arch/arm/boot/dts/uniphier-ld6b-ref.dts | 2 +-
arch/arm/boot/dts/uniphier-pro4-ref.dts | 2 +-
arch/arm/boot/dts/uniphier-pro4.dtsi | 27 +++++++++++++++++++
arch/arm/boot/dts/uniphier-pro5.dtsi | 33 ++++++++++++++++++++++++
arch/arm/boot/dts/uniphier-pxs2.dtsi | 19 ++++++++++++++
arch/arm/boot/dts/uniphier-sld8-ref.dts | 2 +-
arch/arm/boot/dts/uniphier-sld8.dtsi | 23 +++++++++++++++++
9 files changed, 129 insertions(+), 4 deletions(-)
--
Best Regards
Masahiro Yamada
^ permalink raw reply
* [GIT PULL] arm64: dts: uniphier: UniPhier DT updates (64bit) for v4.16
From: Masahiro Yamada @ 2017-12-29 13:35 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd, Olof,
Here are UniPhier DT (64bit) updates for the v4.16 merge window.
Please pull!
The following changes since commit 50c4c4e268a2d7a3e58ebb698ac74da0de40ae36:
Linux 4.15-rc3 (2017-12-10 17:56:26 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git
tags/uniphier-dt64-v4.16
for you to fetch changes up to dbdae8474e08fc1194102bef95dc96db435c15da:
arm64: dts: uniphier: enable more serial ports for PXs3 ref board
(2017-12-29 22:03:26 +0900)
----------------------------------------------------------------
UniPhier ARM64 SoC DT updates for v4.16
- clean up gpios properties by macro
- add GPIO hog for PXs3 reference node
- add has-transaction-translator property to generic-ehci nodes
- enable more serial ports for PXs3 reference node
----------------------------------------------------------------
Kunihiko Hayashi (1):
arm64: dts: uniphier: add has-transaction-translator property to
usb node for LD11
Masahiro Yamada (3):
arm64: dts: uniphier: use macros in dt-bindings header
arm64: dts: uniphier: add GPIO hog definition for PXs3
arm64: dts: uniphier: enable more serial ports for PXs3 ref board
.../boot/dts/socionext/uniphier-ld11-ref.dts | 2 +-
.../arm64/boot/dts/socionext/uniphier-ld11.dtsi | 6 +++++-
.../boot/dts/socionext/uniphier-ld20-ref.dts | 2 +-
.../arm64/boot/dts/socionext/uniphier-ld20.dtsi | 3 ++-
.../boot/dts/socionext/uniphier-pxs3-ref.dts | 16 ++++++++++++++++
.../arm64/boot/dts/socionext/uniphier-pxs3.dtsi | 3 ++-
6 files changed, 27 insertions(+), 5 deletions(-)
--
Best Regards
Masahiro Yamada
^ permalink raw reply
* [PATCH v2 1/5] ARM: sun9i: Support SMP on A80 with Multi-Cluster Power Management (MCPM)
From: Philippe Ombredanne @ 2017-12-29 13:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171229105506.24851-2-mylene.josserand@free-electrons.com>
Myl?ne, Chen-Yu,
On Fri, Dec 29, 2017 at 11:55 AM, Myl?ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> From: Chen-Yu Tsai <wens@csie.org>
>
> The A80 is a big.LITTLE SoC with 1 cluster of 4 Cortex-A7s and
> 1 cluster of 4 Cortex-A15s.
<snip>
> --- /dev/null
> +++ b/arch/arm/mach-sunxi/mcpm.c
> @@ -0,0 +1,391 @@
> +/*
> + * Copyright (c) 2015 Chen-Yu Tsai
> + *
> + * Chen-Yu Tsai <wens@csie.org>
> + *
> + * arch/arm/mach-sunxi/mcpm.c
> + *
> + * Based on arch/arm/mach-exynos/mcpm-exynos.c and Allwinner code
> + *
> + * 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.
> + */
Would you mind using a concise SPDX tag instead, as documented by
Thomas doc patches?
Thank you for your kind consideration!
--
Cordially
Philippe Ombredanne
^ permalink raw reply
* [PATCH 27/67] dma-direct: add dma address sanity checks
From: Geert Uytterhoeven @ 2017-12-29 14:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171229081911.2802-28-hch@lst.de>
Hi Christoph,
On Fri, Dec 29, 2017 at 9:18 AM, Christoph Hellwig <hch@lst.de> wrote:
> Roughly based on the x86 pci-nommu implementation.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Thanks for your patch!
> --- a/lib/dma-direct.c
> +++ b/lib/dma-direct.c
> @@ -9,6 +9,24 @@
> #include <linux/scatterlist.h>
> #include <linux/pfn.h>
>
> +#define DIRECT_MAPPING_ERROR 0
> +
> +static bool
> +check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
> + const char *caller)
> +{
> + if (unlikely(dev && !dma_capable(dev, dma_addr, size))) {
> + if (*dev->dma_mask >= DMA_BIT_MASK(32)) {
> + dev_err(dev,
> + "%s: overflow %llx+%zu of device mask %llx\n",
Please use "%pad" to format dma_addr_t ...
> + caller, (long long)dma_addr, size,
... and use &dma_addr.
> + (long long)*dev->dma_mask);
This cast is not needed, as u64 is unsigned long long in kernelspace on
all architectures.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH 02/14] iio: Add channel for Position
From: Jonathan Cameron @ 2017-12-29 16:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513955241-10985-3-git-send-email-eugen.hristev@microchip.com>
On Fri, 22 Dec 2017 17:07:09 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> Add new channel type for position on a pad.
>
> These type of analog sensor represents the position of a pen
> on a touchpad, and is represented as a voltage, which can be
> converted to a position on X and Y axis on the pad.
>
> The channel can then be consumed by a touchscreen driver or
> read as-is for a raw indication of the touchpen on a touchpad.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 11 +++++++++++
> drivers/iio/industrialio-core.c | 1 +
> include/uapi/linux/iio/types.h | 1 +
> tools/iio/iio_event_monitor.c | 2 ++
> 4 files changed, 15 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index a478740..d2b9e2f 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -190,6 +190,17 @@ Description:
> but should match other such assignments on device).
> Units after application of scale and offset are m/s^2.
>
> +What: /sys/bus/iio/devices/iio:deviceX/in_position_x_raw
> +What: /sys/bus/iio/devices/iio:deviceX/in_position_y_raw
> +KernelVersion: 4.16
> +Contact: linux-iio at vger.kernel.org
> +Description:
> + Position in direction x or y on a pad (may be arbitrarily
> + assigned but should match other such assignments on device).
> + Units after application of scale and offset are millipercents
> + from the pad's size in both directions. Should be calibrated by
> + the consumer.
Hmm. The units are an issues as to be consistent with the existing ABI position
should be in meters. Perhaps the trick is to do similar to we have done for
relative humidity and call this in_positionrelative_x_raw etc.
That leaves position open for absolute position devices (who knows what)
in the future.
> +
> What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_raw
> What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_raw
> What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_raw
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 2e8e36f..a4fa49b 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -85,6 +85,7 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_COUNT] = "count",
> [IIO_INDEX] = "index",
> [IIO_GRAVITY] = "gravity",
> + [IIO_POSITION] = "position",
> };
>
> static const char * const iio_modifier_names[] = {
> diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
> index 4213cdf..35e17da 100644
> --- a/include/uapi/linux/iio/types.h
> +++ b/include/uapi/linux/iio/types.h
> @@ -44,6 +44,7 @@ enum iio_chan_type {
> IIO_COUNT,
> IIO_INDEX,
> IIO_GRAVITY,
> + IIO_POSITION,
> };
>
> enum iio_modifier {
> diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
> index b61245e..0c2b317 100644
> --- a/tools/iio/iio_event_monitor.c
> +++ b/tools/iio/iio_event_monitor.c
> @@ -58,6 +58,7 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_PH] = "ph",
> [IIO_UVINDEX] = "uvindex",
> [IIO_GRAVITY] = "gravity",
> + [IIO_POSITION] = "position",
> };
>
> static const char * const iio_ev_type_text[] = {
> @@ -151,6 +152,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_PH:
> case IIO_UVINDEX:
> case IIO_GRAVITY:
> + case IIO_POSITION:
> break;
> default:
> return false;
^ permalink raw reply
* [PATCH 0/4] Armada 7K/8K CP110 DT de-duplication
From: Thomas Petazzoni @ 2017-12-29 16:17 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This series aims at de-duplicating the Armada CP110 Device Tree
description, which is currently duplicated between
armada-cp110-master.dtsi and armada-cp110-slave.dtsi, even though they
are almost identical. Indeed, one concept of Marvell SoCs is that they
are made of HW blocks composed of a variety of IPs (network, PCIe,
SATA, XOR, SPI, I2C, etc.), and those HW blocks can be duplicated
several times within a given SoC. The Armada 7K SoC has a single CP110
(so no duplication), while the Armada 8K SoC has two CP110. In the
future, SoCs with more than 2 CP110s will be introduced.
This duplication issue has been discussed at the DT workshop [1] in
Prague last October, and I presented on this topic [2]. The solution
of using the C pre-processor to avoid this duplication has been
validated by the people present in this DT workshop, and this patch
series simply submits what has been presented.
The first three patches are minor preparation patches. The patch
making use of aliases for SPI busses simply aims at reducing the
number of changes between the CP110 master and CP110 slave
description, by avoiding the need for the cell-index property in the
SPI controller DT nodes.
The last patch implements the de-duplication itself, by introducing an
armada-cp110.dtsi file included twice on Armada 8K platforms, once for
the master CP110 and once for the slave CP110.
Note: this series is based on mvebu/dt64-nand, since it is the branch
that contains the most up-to-date DT changes for the Marvell Armada
7K/8K platforms. When PATCH 4/4 is applied, I recommend checking that
the DTB contents are the same before/after. To achieve that, just
build the dtb before/after, "decompile" it with "dtc -I dtb -O dts",
and diff the result. The only difference should be the SDHCI
controller appearing in the slave CP (see the commit log of PATCH 4/4
for details about this).
Thanks!
Thomas
[1] https://elinux.org/Device_tree_kernel_summit_2017_etherpad
[2] https://elinux.org/images/1/14/DTWorkshop2017-duplicate-data.pdf
Thomas Petazzoni (4):
arm64: dts: marvell: fix watchdog unit address in Armada AP806
arm64: dts: marvell: use mvebu-icu.h where possible
arm64: dts: marvell: use aliases for SPI busses on Armada 7K/8K
arm64: dts: marvell: de-duplicate CP110 description
arch/arm64/boot/dts/marvell/armada-70x0.dtsi | 2 +
arch/arm64/boot/dts/marvell/armada-80x0.dtsi | 4 +
arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 4 +-
arch/arm64/boot/dts/marvell/armada-common.dtsi | 10 +
.../boot/dts/marvell/armada-cp110-master.dtsi | 406 +-------------------
.../arm64/boot/dts/marvell/armada-cp110-slave.dtsi | 414 ++-------------------
arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 398 ++++++++++++++++++++
7 files changed, 465 insertions(+), 773 deletions(-)
create mode 100644 arch/arm64/boot/dts/marvell/armada-common.dtsi
create mode 100644 arch/arm64/boot/dts/marvell/armada-cp110.dtsi
--
2.14.3
^ permalink raw reply
* [PATCH 1/4] arm64: dts: marvell: fix watchdog unit address in Armada AP806
From: Thomas Petazzoni @ 2017-12-29 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171229161718.8896-1-thomas.petazzoni@free-electrons.com>
This fixes the following DTC warning:
Warning (simple_bus_reg): Node /ap806/config-space at f0000000/watchdog at 600000 simple-bus unit address format error, expected "610000"
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 1c4dd8ab9ad5..7ef72d98f32b 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -241,7 +241,7 @@
};
- watchdog: watchdog at 600000 {
+ watchdog: watchdog at 610000 {
compatible = "arm,sbsa-gwdt";
reg = <0x610000 0x1000>, <0x600000 0x1000>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
--
2.14.3
^ permalink raw reply related
* [PATCH 2/4] arm64: dts: marvell: use mvebu-icu.h where possible
From: Thomas Petazzoni @ 2017-12-29 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171229161718.8896-1-thomas.petazzoni@free-electrons.com>
Back when the ICU Device Tree binding was introduced, we could not use
mvebu-icu.h from the Device Tree files, because the DT files and
mvebu-icu.h were following different merge routes towards Linus
tree. Now that both have been merged, we can switch the Marvell Armada
CP110 Device Tree files to use the mvebu-icu.h header instead of
duplicating the ICU_GRP_NSR definition.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi | 2 +-
arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index 8a3cff9a7343..69ef3305b3e7 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -44,7 +44,7 @@
* Device Tree file for Marvell Armada CP110 Master.
*/
-#define ICU_GRP_NSR 0x0
+#include <dt-bindings/interrupt-controller/mvebu-icu.h>
/ {
cp110-master {
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
index 8610163bb1a4..1458f312497b 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -44,7 +44,7 @@
* Device Tree file for Marvell Armada CP110 Slave.
*/
-#define ICU_GRP_NSR 0x0
+#include <dt-bindings/interrupt-controller/mvebu-icu.h>
/ {
cp110-slave {
--
2.14.3
^ permalink raw reply related
* [PATCH 3/4] arm64: dts: marvell: use aliases for SPI busses on Armada 7K/8K
From: Thomas Petazzoni @ 2017-12-29 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171229161718.8896-1-thomas.petazzoni@free-electrons.com>
We are currently using the cell-index DT property to assign SPI bus
numbers. This property is specific to the spi-orion driver, and
requires each SPI controller to have a unique ID defined in the Device
Tree.
As we are about to merge armada-cp110-master.dtsi and
armada-cp110-slave.dtsi into a single file, those cell-index
properties that differ between the master CP110 and the slave CP110
are a difference that would have to be handled.
In order to avoid this, we switch to using the "aliases" DT node to
assign a unique number to each SPI controller. This is more generic,
and directly handled by the SPI core.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-70x0.dtsi | 2 ++
arch/arm64/boot/dts/marvell/armada-80x0.dtsi | 4 ++++
arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 2 +-
arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi | 2 --
arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi | 2 --
5 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-70x0.dtsi b/arch/arm64/boot/dts/marvell/armada-70x0.dtsi
index 0e1a1e5be399..815e64b3a874 100644
--- a/arch/arm64/boot/dts/marvell/armada-70x0.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-70x0.dtsi
@@ -50,6 +50,8 @@
aliases {
gpio1 = &cpm_gpio1;
gpio2 = &cpm_gpio2;
+ spi1 = &cpm_spi0;
+ spi2 = &cpm_spi1;
};
};
diff --git a/arch/arm64/boot/dts/marvell/armada-80x0.dtsi b/arch/arm64/boot/dts/marvell/armada-80x0.dtsi
index b280ddd3c397..de9c34333cd4 100644
--- a/arch/arm64/boot/dts/marvell/armada-80x0.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-80x0.dtsi
@@ -51,6 +51,10 @@
aliases {
gpio1 = &cps_gpio1;
gpio2 = &cpm_gpio2;
+ spi1 = &cpm_spi0;
+ spi2 = &cpm_spi1;
+ spi3 = &cps_spi0;
+ spi4 = &cps_spi1;
};
};
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 7ef72d98f32b..8bf318dbd674 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -58,6 +58,7 @@
serial0 = &uart0;
serial1 = &uart1;
gpio0 = &ap_gpio;
+ spi0 = &spi0;
};
psci {
@@ -203,7 +204,6 @@
reg = <0x510600 0x50>;
#address-cells = <1>;
#size-cells = <0>;
- cell-index = <0>;
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ap_clk 3>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index 69ef3305b3e7..37d2151bf1c7 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -274,7 +274,6 @@
reg = <0x700600 0x50>;
#address-cells = <0x1>;
#size-cells = <0x0>;
- cell-index = <1>;
clocks = <&cpm_clk 1 21>;
status = "disabled";
};
@@ -284,7 +283,6 @@
reg = <0x700680 0x50>;
#address-cells = <1>;
#size-cells = <0>;
- cell-index = <2>;
clocks = <&cpm_clk 1 21>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
index 1458f312497b..646db0938a28 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -275,7 +275,6 @@
reg = <0x700600 0x50>;
#address-cells = <0x1>;
#size-cells = <0x0>;
- cell-index = <3>;
clocks = <&cps_clk 1 21>;
status = "disabled";
};
@@ -285,7 +284,6 @@
reg = <0x700680 0x50>;
#address-cells = <1>;
#size-cells = <0>;
- cell-index = <4>;
clocks = <&cps_clk 1 21>;
status = "disabled";
};
--
2.14.3
^ permalink raw reply related
* [PATCH 4/4] arm64: dts: marvell: de-duplicate CP110 description
From: Thomas Petazzoni @ 2017-12-29 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171229161718.8896-1-thomas.petazzoni@free-electrons.com>
One concept of Marvell Armada 7K/8K SoCs is that they are made of HW
blocks composed of a variety of IPs (network, PCIe, SATA, XOR, SPI,
I2C, etc.), and those HW blocks can be duplicated several times within
a given SoC. The Armada 7K SoC has a single CP110 (so no duplication),
while the Armada 8K SoC has two CP110. In the future, SoCs with more
than 2 CP110s will be introduced.
In current kernel versions, the master CP110 is described in
armada-cp110-master.dtsi and the slave CP110 is described in
armada-cp110-slave.dtsi. Those files are basically exactly the same,
since they describe the same hardware. They only have a few
differences:
- Base address of the registers is different for the "config-space"
- Base address of the PCIe registers, MEM, CONF and IO areas were
different
- Labels (and phandles pointing to them) of the nodes were different
("cpm" prefix in the master CP, "cps" prefix in the slave CP)
This duplication issue has been discussed at the DT workshop [1] in
Prague last October, and we presented on this topic [2]. The solution
of using the C pre-processor to avoid this duplication has been
validated by the people present in this DT workshop, and this patch
simply implements what has been presented.
We handle differences between the master CP and slave CP description
using the C pre-processor, by defining a set of macros with different
values armada-cp110.dtsi is included to instantiate one of the master
or slave CP110.
There are a few aspects that deserve additional explanations:
- PCIe needs to be handled separately because it is not part of the
config-space {...} node, since it has registers outside of the
range covered by config-space {...}.
- We need to defined CP110_BASE, CP110_PCIEx_BASE without 0x, because
they are used for the unit address part of some DT nodes. But since
they are also used for the "reg" property of the same nodes, we
have an ADDRESSIFY() macro that prepends 0x to those values.
We compared the resulting .dtb for armada-8040-db.dtb before and after
this patch is applied, and the result is exactly the same, except for
one difference: the SDHCI controller that was only described in the
master CP110 is now also described in the slave CP110. Even though the
SDHCI controller from the slave CP110 is indeed not usable (as it
isn't wired to the outside world) it is technically part of the
silicon, and therefore it is reasonable to also describe it to be part
of the slave CP110. In addition, if we wanted to get this correct for
the SDHCI controller, we should also do it for the NAND controller,
for which the situation is even more complicated: in a single CP110
configuration (Armada 7K), the usable NAND controller is in the master
CP110, while in a dual CP110 configuration (Armada 8K), the usable
NAND controller is in the slave CP110. Since that would add a lot of
additional complexity for no good reason, and since the IP blocks are
in fact really present in both CPs, we simply describe them in both
CPs at the DT level.
[1] https://elinux.org/Device_tree_kernel_summit_2017_etherpad
[2] https://elinux.org/images/1/14/DTWorkshop2017-duplicate-data.pdf
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-common.dtsi | 10 +
.../boot/dts/marvell/armada-cp110-master.dtsi | 402 +-------------------
.../arm64/boot/dts/marvell/armada-cp110-slave.dtsi | 410 ++-------------------
arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 398 ++++++++++++++++++++
4 files changed, 455 insertions(+), 765 deletions(-)
create mode 100644 arch/arm64/boot/dts/marvell/armada-common.dtsi
create mode 100644 arch/arm64/boot/dts/marvell/armada-cp110.dtsi
diff --git a/arch/arm64/boot/dts/marvell/armada-common.dtsi b/arch/arm64/boot/dts/marvell/armada-common.dtsi
new file mode 100644
index 000000000000..c6dd1d81c68d
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/armada-common.dtsi
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR X11)
+/*
+ * Copyright (C) 2016 Marvell Technology Group Ltd.
+ */
+
+/* Common definitions used by Armada 7K/8K DTs */
+#define PASTER(x, y) x ## y
+#define EVALUATOR(x, y) PASTER(x, y)
+#define CP110_LABEL(name) EVALUATOR(CP110_NAME, EVALUATOR(_, name))
+#define ADDRESSIFY(addr) EVALUATOR(0x, addr)
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index 37d2151bf1c7..c9e9ee85f520 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -46,6 +46,16 @@
#include <dt-bindings/interrupt-controller/mvebu-icu.h>
+#include "armada-common.dtsi"
+
+#define CP110_NAME cpm
+#define CP110_BASE f2000000
+#define CP110_PCIE_IO_BASE 0xf9000000
+#define CP110_PCIE_MEM_BASE 0xf6000000
+#define CP110_PCIE0_BASE f2600000
+#define CP110_PCIE1_BASE f2620000
+#define CP110_PCIE2_BASE f2640000
+
/ {
cp110-master {
#address-cells = <2>;
@@ -54,388 +64,14 @@
interrupt-parent = <&cpm_icu>;
ranges;
- config-space at f2000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "simple-bus";
- ranges = <0x0 0x0 0xf2000000 0x2000000>;
-
- cpm_ethernet: ethernet at 0 {
- compatible = "marvell,armada-7k-pp22";
- reg = <0x0 0x100000>, <0x129000 0xb000>;
- clocks = <&cpm_clk 1 3>, <&cpm_clk 1 9>, <&cpm_clk 1 5>;
- clock-names = "pp_clk", "gop_clk", "mg_clk";
- marvell,system-controller = <&cpm_syscon0>;
- status = "disabled";
- dma-coherent;
-
- cpm_eth0: eth0 {
- interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 43 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 47 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 51 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 55 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 129 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
- "tx-cpu3", "rx-shared", "link";
- port-id = <0>;
- gop-port-id = <0>;
- status = "disabled";
- };
-
- cpm_eth1: eth1 {
- interrupts = <ICU_GRP_NSR 40 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 44 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 48 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 52 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 56 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 128 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
- "tx-cpu3", "rx-shared", "link";
- port-id = <1>;
- gop-port-id = <2>;
- status = "disabled";
- };
-
- cpm_eth2: eth2 {
- interrupts = <ICU_GRP_NSR 41 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 45 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 49 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 53 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 57 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 127 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
- "tx-cpu3", "rx-shared", "link";
- port-id = <2>;
- gop-port-id = <3>;
- status = "disabled";
- };
- };
-
- cpm_comphy: phy at 120000 {
- compatible = "marvell,comphy-cp110";
- reg = <0x120000 0x6000>;
- marvell,system-controller = <&cpm_syscon0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpm_comphy0: phy at 0 {
- reg = <0>;
- #phy-cells = <1>;
- };
-
- cpm_comphy1: phy at 1 {
- reg = <1>;
- #phy-cells = <1>;
- };
-
- cpm_comphy2: phy at 2 {
- reg = <2>;
- #phy-cells = <1>;
- };
-
- cpm_comphy3: phy at 3 {
- reg = <3>;
- #phy-cells = <1>;
- };
-
- cpm_comphy4: phy at 4 {
- reg = <4>;
- #phy-cells = <1>;
- };
-
- cpm_comphy5: phy at 5 {
- reg = <5>;
- #phy-cells = <1>;
- };
- };
-
- cpm_mdio: mdio at 12a200 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,orion-mdio";
- reg = <0x12a200 0x10>;
- clocks = <&cpm_clk 1 9>, <&cpm_clk 1 5>;
- status = "disabled";
- };
-
- cpm_xmdio: mdio at 12a600 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,xmdio";
- reg = <0x12a600 0x10>;
- status = "disabled";
- };
-
- cpm_icu: interrupt-controller at 1e0000 {
- compatible = "marvell,cp110-icu";
- reg = <0x1e0000 0x10>;
- #interrupt-cells = <3>;
- interrupt-controller;
- msi-parent = <&gicp>;
- };
-
- cpm_rtc: rtc at 284000 {
- compatible = "marvell,armada-8k-rtc";
- reg = <0x284000 0x20>, <0x284080 0x24>;
- reg-names = "rtc", "rtc-soc";
- interrupts = <ICU_GRP_NSR 77 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- cpm_syscon0: system-controller at 440000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x440000 0x2000>;
-
- cpm_clk: clock {
- compatible = "marvell,cp110-clock";
- #clock-cells = <2>;
- };
-
- cpm_gpio1: gpio at 100 {
- compatible = "marvell,armada-8k-gpio";
- offset = <0x100>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&cpm_pinctrl 0 0 32>;
- interrupt-controller;
- interrupts = <ICU_GRP_NSR 86 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 85 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 84 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 83 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
- };
-
- cpm_gpio2: gpio at 140 {
- compatible = "marvell,armada-8k-gpio";
- offset = <0x140>;
- ngpios = <31>;
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&cpm_pinctrl 0 32 31>;
- interrupt-controller;
- interrupts = <ICU_GRP_NSR 82 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 81 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 80 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 79 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
- };
- };
-
- cpm_usb3_0: usb3 at 500000 {
- compatible = "marvell,armada-8k-xhci",
- "generic-xhci";
- reg = <0x500000 0x4000>;
- dma-coherent;
- interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpm_clk 1 22>;
- status = "disabled";
- };
-
- cpm_usb3_1: usb3 at 510000 {
- compatible = "marvell,armada-8k-xhci",
- "generic-xhci";
- reg = <0x510000 0x4000>;
- dma-coherent;
- interrupts = <ICU_GRP_NSR 105 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpm_clk 1 23>;
- status = "disabled";
- };
-
- cpm_sata0: sata at 540000 {
- compatible = "marvell,armada-8k-ahci",
- "generic-ahci";
- reg = <0x540000 0x30000>;
- interrupts = <ICU_GRP_NSR 107 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpm_clk 1 15>;
- status = "disabled";
- };
-
- cpm_xor0: xor at 6a0000 {
- compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
- reg = <0x6a0000 0x1000>,
- <0x6b0000 0x1000>;
- dma-coherent;
- msi-parent = <&gic_v2m0>;
- clocks = <&cpm_clk 1 8>;
- };
-
- cpm_xor1: xor at 6c0000 {
- compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
- reg = <0x6c0000 0x1000>,
- <0x6d0000 0x1000>;
- dma-coherent;
- msi-parent = <&gic_v2m0>;
- clocks = <&cpm_clk 1 7>;
- };
-
- cpm_spi0: spi at 700600 {
- compatible = "marvell,armada-380-spi";
- reg = <0x700600 0x50>;
- #address-cells = <0x1>;
- #size-cells = <0x0>;
- clocks = <&cpm_clk 1 21>;
- status = "disabled";
- };
-
- cpm_spi1: spi at 700680 {
- compatible = "marvell,armada-380-spi";
- reg = <0x700680 0x50>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&cpm_clk 1 21>;
- status = "disabled";
- };
-
- cpm_i2c0: i2c at 701000 {
- compatible = "marvell,mv78230-i2c";
- reg = <0x701000 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <ICU_GRP_NSR 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpm_clk 1 21>;
- status = "disabled";
- };
-
- cpm_i2c1: i2c at 701100 {
- compatible = "marvell,mv78230-i2c";
- reg = <0x701100 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <ICU_GRP_NSR 121 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpm_clk 1 21>;
- status = "disabled";
- };
-
- cpm_nand_controller: nand at 720000 {
- /*
- * Due to the limiation of the pin available
- * this controller is only usable on the CPM
- * for A7K and on the CPS for A8K.
- */
- compatible = "marvell,armada-8k-nand-controller",
- "marvell,armada370-nand-controller";
- reg = <0x720000 0x54>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <ICU_GRP_NSR 115 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpm_clk 1 2>;
- marvell,system-controller = <&cpm_syscon0>;
- status = "disabled";
- };
-
- cpm_trng: trng at 760000 {
- compatible = "marvell,armada-8k-rng", "inside-secure,safexcel-eip76";
- reg = <0x760000 0x7d>;
- interrupts = <ICU_GRP_NSR 95 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpm_clk 1 25>;
- status = "okay";
- };
-
- cpm_sdhci0: sdhci at 780000 {
- compatible = "marvell,armada-cp110-sdhci";
- reg = <0x780000 0x300>;
- interrupts = <ICU_GRP_NSR 27 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "core";
- clocks = <&cpm_clk 1 4>;
- dma-coherent;
- status = "disabled";
- };
-
- cpm_crypto: crypto at 800000 {
- compatible = "inside-secure,safexcel-eip197";
- reg = <0x800000 0x200000>;
- interrupts = <ICU_GRP_NSR 87 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 88 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 89 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 90 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 91 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 92 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "mem", "ring0", "ring1",
- "ring2", "ring3", "eip";
- clocks = <&cpm_clk 1 26>;
- dma-coherent;
- };
- };
-
- cpm_pcie0: pcie at f2600000 {
- compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
- reg = <0 0xf2600000 0 0x10000>,
- <0 0xf6f00000 0 0x80000>;
- reg-names = "ctrl", "config";
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- device_type = "pci";
- dma-coherent;
- msi-parent = <&gic_v2m0>;
-
- bus-range = <0 0xff>;
- ranges =
- /* downstream I/O */
- <0x81000000 0 0xf9000000 0 0xf9000000 0 0x10000
- /* non-prefetchable memory */
- 0x82000000 0 0xf6000000 0 0xf6000000 0 0xf00000>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
- interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
- num-lanes = <1>;
- clocks = <&cpm_clk 1 13>;
- status = "disabled";
- };
-
- cpm_pcie1: pcie at f2620000 {
- compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
- reg = <0 0xf2620000 0 0x10000>,
- <0 0xf7f00000 0 0x80000>;
- reg-names = "ctrl", "config";
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- device_type = "pci";
- dma-coherent;
- msi-parent = <&gic_v2m0>;
-
- bus-range = <0 0xff>;
- ranges =
- /* downstream I/O */
- <0x81000000 0 0xf9010000 0 0xf9010000 0 0x10000
- /* non-prefetchable memory */
- 0x82000000 0 0xf7000000 0 0xf7000000 0 0xf00000>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
- interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
-
- num-lanes = <1>;
- clocks = <&cpm_clk 1 11>;
- status = "disabled";
- };
-
- cpm_pcie2: pcie at f2640000 {
- compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
- reg = <0 0xf2640000 0 0x10000>,
- <0 0xf8f00000 0 0x80000>;
- reg-names = "ctrl", "config";
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- device_type = "pci";
- dma-coherent;
- msi-parent = <&gic_v2m0>;
-
- bus-range = <0 0xff>;
- ranges =
- /* downstream I/O */
- <0x81000000 0 0xf9020000 0 0xf9020000 0 0x10000
- /* non-prefetchable memory */
- 0x82000000 0 0xf8000000 0 0xf8000000 0 0xf00000>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
- interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
-
- num-lanes = <1>;
- clocks = <&cpm_clk 1 12>;
- status = "disabled";
- };
+ #include "armada-cp110.dtsi"
};
};
+
+#undef CP110_NAME
+#undef CP110_BASE
+#undef CP110_PCIE_IO_BASE
+#undef CP110_PCIE_MEM_BASE
+#undef CP110_PCIE0_BASE
+#undef CP110_PCIE1_BASE
+#undef CP110_PCIE2_BASE
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
index 646db0938a28..1f9d10ba27d1 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -46,6 +46,14 @@
#include <dt-bindings/interrupt-controller/mvebu-icu.h>
+#define CP110_NAME cps
+#define CP110_BASE f4000000
+#define CP110_PCIE_IO_BASE 0xfd000000
+#define CP110_PCIE_MEM_BASE 0xfa000000
+#define CP110_PCIE0_BASE f4600000
+#define CP110_PCIE1_BASE f4620000
+#define CP110_PCIE2_BASE f4640000
+
/ {
cp110-slave {
#address-cells = <2>;
@@ -54,387 +62,25 @@
interrupt-parent = <&cps_icu>;
ranges;
- config-space at f4000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "simple-bus";
- ranges = <0x0 0x0 0xf4000000 0x2000000>;
-
- cps_ethernet: ethernet at 0 {
- compatible = "marvell,armada-7k-pp22";
- reg = <0x0 0x100000>, <0x129000 0xb000>;
- clocks = <&cps_clk 1 3>, <&cps_clk 1 9>, <&cps_clk 1 5>;
- clock-names = "pp_clk", "gop_clk", "mg_clk";
- marvell,system-controller = <&cps_syscon0>;
- status = "disabled";
- dma-coherent;
-
- cps_eth0: eth0 {
- interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 43 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 47 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 51 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 55 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 129 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
- "tx-cpu3", "rx-shared", "link";
- port-id = <0>;
- gop-port-id = <0>;
- status = "disabled";
- };
-
- cps_eth1: eth1 {
- interrupts = <ICU_GRP_NSR 40 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 44 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 48 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 52 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 56 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 128 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
- "tx-cpu3", "rx-shared", "link";
- port-id = <1>;
- gop-port-id = <2>;
- status = "disabled";
- };
-
- cps_eth2: eth2 {
- interrupts = <ICU_GRP_NSR 41 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 45 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 49 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 53 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 57 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 127 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
- "tx-cpu3", "rx-shared", "link";
- port-id = <2>;
- gop-port-id = <3>;
- status = "disabled";
- };
- };
-
- cps_comphy: phy at 120000 {
- compatible = "marvell,comphy-cp110";
- reg = <0x120000 0x6000>;
- marvell,system-controller = <&cps_syscon0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- cps_comphy0: phy at 0 {
- reg = <0>;
- #phy-cells = <1>;
- };
-
- cps_comphy1: phy at 1 {
- reg = <1>;
- #phy-cells = <1>;
- };
-
- cps_comphy2: phy at 2 {
- reg = <2>;
- #phy-cells = <1>;
- };
-
- cps_comphy3: phy at 3 {
- reg = <3>;
- #phy-cells = <1>;
- };
-
- cps_comphy4: phy at 4 {
- reg = <4>;
- #phy-cells = <1>;
- };
-
- cps_comphy5: phy at 5 {
- reg = <5>;
- #phy-cells = <1>;
- };
- };
-
- cps_mdio: mdio at 12a200 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,orion-mdio";
- reg = <0x12a200 0x10>;
- clocks = <&cps_clk 1 9>, <&cps_clk 1 5>;
- status = "disabled";
- };
-
- cps_xmdio: mdio at 12a600 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,xmdio";
- reg = <0x12a600 0x10>;
- status = "disabled";
- };
-
- cps_icu: interrupt-controller at 1e0000 {
- compatible = "marvell,cp110-icu";
- reg = <0x1e0000 0x10>;
- #interrupt-cells = <3>;
- interrupt-controller;
- msi-parent = <&gicp>;
- };
-
- cps_rtc: rtc at 284000 {
- compatible = "marvell,armada-8k-rtc";
- reg = <0x284000 0x20>, <0x284080 0x24>;
- reg-names = "rtc", "rtc-soc";
- interrupts = <ICU_GRP_NSR 77 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- cps_syscon0: system-controller at 440000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x440000 0x2000>;
-
- cps_clk: clock {
- compatible = "marvell,cp110-clock";
- #clock-cells = <2>;
- };
-
- cps_gpio1: gpio at 100 {
- compatible = "marvell,armada-8k-gpio";
- offset = <0x100>;
- ngpios = <32>;
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&cps_pinctrl 0 0 32>;
- interrupt-controller;
- interrupts = <ICU_GRP_NSR 86 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 85 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 84 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 83 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
- };
-
- cps_gpio2: gpio at 140 {
- compatible = "marvell,armada-8k-gpio";
- offset = <0x140>;
- ngpios = <31>;
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&cps_pinctrl 0 32 31>;
- interrupt-controller;
- interrupts = <ICU_GRP_NSR 82 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 81 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 80 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 79 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
- };
-
- };
-
- cps_usb3_0: usb3 at 500000 {
- compatible = "marvell,armada-8k-xhci",
- "generic-xhci";
- reg = <0x500000 0x4000>;
- dma-coherent;
- interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cps_clk 1 22>;
- status = "disabled";
- };
-
- cps_usb3_1: usb3 at 510000 {
- compatible = "marvell,armada-8k-xhci",
- "generic-xhci";
- reg = <0x510000 0x4000>;
- dma-coherent;
- interrupts = <ICU_GRP_NSR 105 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cps_clk 1 23>;
- status = "disabled";
- };
-
- cps_sata0: sata at 540000 {
- compatible = "marvell,armada-8k-ahci",
- "generic-ahci";
- reg = <0x540000 0x30000>;
- interrupts = <ICU_GRP_NSR 107 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cps_clk 1 15>;
- status = "disabled";
- };
-
- cps_xor0: xor at 6a0000 {
- compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
- reg = <0x6a0000 0x1000>,
- <0x6b0000 0x1000>;
- dma-coherent;
- msi-parent = <&gic_v2m0>;
- clocks = <&cps_clk 1 8>;
- };
-
- cps_xor1: xor at 6c0000 {
- compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
- reg = <0x6c0000 0x1000>,
- <0x6d0000 0x1000>;
- dma-coherent;
- msi-parent = <&gic_v2m0>;
- clocks = <&cps_clk 1 7>;
- };
-
- cps_spi0: spi at 700600 {
- compatible = "marvell,armada-380-spi";
- reg = <0x700600 0x50>;
- #address-cells = <0x1>;
- #size-cells = <0x0>;
- clocks = <&cps_clk 1 21>;
- status = "disabled";
- };
-
- cps_spi1: spi at 700680 {
- compatible = "marvell,armada-380-spi";
- reg = <0x700680 0x50>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&cps_clk 1 21>;
- status = "disabled";
- };
-
- cps_i2c0: i2c at 701000 {
- compatible = "marvell,mv78230-i2c";
- reg = <0x701000 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <ICU_GRP_NSR 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cps_clk 1 21>;
- status = "disabled";
- };
-
- cps_i2c1: i2c at 701100 {
- compatible = "marvell,mv78230-i2c";
- reg = <0x701100 0x20>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <ICU_GRP_NSR 121 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cps_clk 1 21>;
- status = "disabled";
- };
-
- cps_nand_controller: nand at 720000 {
- /*
- * Due to the limiation of the pin available
- * this controller is only usable on the CPM
- * for A7K and on the CPS for A8K.
- */
- compatible = "marvell,armada-8k-nand-controller",
- "marvell,armada370-nand-controller";
- reg = <0x720000 0x54>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <ICU_GRP_NSR 115 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cps_clk 1 2>;
- marvell,system-controller = <&cps_syscon0>;
- status = "disabled";
- };
-
- cps_trng: trng at 760000 {
- compatible = "marvell,armada-8k-rng", "inside-secure,safexcel-eip76";
- reg = <0x760000 0x7d>;
- interrupts = <ICU_GRP_NSR 95 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cps_clk 1 25>;
- status = "okay";
- };
-
- cps_crypto: crypto at 800000 {
- compatible = "inside-secure,safexcel-eip197";
- reg = <0x800000 0x200000>;
- interrupts = <ICU_GRP_NSR 87 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 88 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 89 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 90 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 91 IRQ_TYPE_LEVEL_HIGH>,
- <ICU_GRP_NSR 92 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "mem", "ring0", "ring1",
- "ring2", "ring3", "eip";
- clocks = <&cps_clk 1 26>;
- dma-coherent;
- /*
- * The cryptographic engine found on the cp110
- * master is enabled by default at the SoC
- * level. Because it is not possible as of now
- * to enable two cryptographic engines in
- * parallel, disable this one by default.
- */
- status = "disabled";
- };
- };
-
- cps_pcie0: pcie at f4600000 {
- compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
- reg = <0 0xf4600000 0 0x10000>,
- <0 0xfaf00000 0 0x80000>;
- reg-names = "ctrl", "config";
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- device_type = "pci";
- dma-coherent;
- msi-parent = <&gic_v2m0>;
-
- bus-range = <0 0xff>;
- ranges =
- /* downstream I/O */
- <0x81000000 0 0xfd000000 0 0xfd000000 0 0x10000
- /* non-prefetchable memory */
- 0x82000000 0 0xfa000000 0 0xfa000000 0 0xf00000>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
- interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
- num-lanes = <1>;
- clocks = <&cps_clk 1 13>;
- status = "disabled";
- };
-
- cps_pcie1: pcie at f4620000 {
- compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
- reg = <0 0xf4620000 0 0x10000>,
- <0 0xfbf00000 0 0x80000>;
- reg-names = "ctrl", "config";
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- device_type = "pci";
- dma-coherent;
- msi-parent = <&gic_v2m0>;
-
- bus-range = <0 0xff>;
- ranges =
- /* downstream I/O */
- <0x81000000 0 0xfd010000 0 0xfd010000 0 0x10000
- /* non-prefetchable memory */
- 0x82000000 0 0xfb000000 0 0xfb000000 0 0xf00000>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
- interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
-
- num-lanes = <1>;
- clocks = <&cps_clk 1 11>;
- status = "disabled";
- };
-
- cps_pcie2: pcie at f4640000 {
- compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
- reg = <0 0xf4640000 0 0x10000>,
- <0 0xfcf00000 0 0x80000>;
- reg-names = "ctrl", "config";
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- device_type = "pci";
- dma-coherent;
- msi-parent = <&gic_v2m0>;
-
- bus-range = <0 0xff>;
- ranges =
- /* downstream I/O */
- <0x81000000 0 0xfd020000 0 0xfd020000 0 0x10000
- /* non-prefetchable memory */
- 0x82000000 0 0xfc000000 0 0xfc000000 0 0xf00000>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
- interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
-
- num-lanes = <1>;
- clocks = <&cps_clk 1 12>;
- status = "disabled";
- };
+ #include "armada-cp110.dtsi"
};
};
+
+&cps_crypto {
+ /*
+ * The cryptographic engine found on the cp110
+ * master is enabled by default at the SoC
+ * level. Because it is not possible as of now
+ * to enable two cryptographic engines in
+ * parallel, disable this one by default.
+ */
+ status = "disabled";
+};
+
+#undef CP110_NAME
+#undef CP110_BASE
+#undef CP110_PCIE_IO_BASE
+#undef CP110_PCIE_MEM_BASE
+#undef CP110_PCIE0_BASE
+#undef CP110_PCIE1_BASE
+#undef CP110_PCIE2_BASE
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
new file mode 100644
index 000000000000..93774631e446
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -0,0 +1,398 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR X11)
+/*
+ * Copyright (C) 2016 Marvell Technology Group Ltd.
+ */
+
+/*
+ * Device Tree file for Marvell Armada CP110.
+ */
+
+#include <dt-bindings/interrupt-controller/mvebu-icu.h>
+
+#define CP110_PCIEx_IO_BASE(iface) (CP110_PCIE_IO_BASE + (iface * 0x10000))
+#define CP110_PCIEx_MEM_BASE(iface) (CP110_PCIE_MEM_BASE + (iface * 0x1000000))
+#define CP110_PCIEx_CONF_BASE(iface) (CP110_PCIEx_MEM_BASE(iface) + 0xf00000)
+
+config-space at CP110_BASE {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0x0 ADDRESSIFY(CP110_BASE) 0x2000000>;
+
+ CP110_LABEL(ethernet): ethernet at 0 {
+ compatible = "marvell,armada-7k-pp22";
+ reg = <0x0 0x100000>, <0x129000 0xb000>;
+ clocks = <&CP110_LABEL(clk) 1 3>, <&CP110_LABEL(clk) 1 9>,
+ <&CP110_LABEL(clk) 1 5>;
+ clock-names = "pp_clk", "gop_clk", "mg_clk";
+ marvell,system-controller = <&CP110_LABEL(syscon0)>;
+ status = "disabled";
+ dma-coherent;
+
+ CP110_LABEL(eth0): eth0 {
+ interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 43 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 47 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 51 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 55 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 129 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
+ "tx-cpu3", "rx-shared", "link";
+ port-id = <0>;
+ gop-port-id = <0>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(eth1): eth1 {
+ interrupts = <ICU_GRP_NSR 40 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 44 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 48 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 52 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 56 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 128 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
+ "tx-cpu3", "rx-shared", "link";
+ port-id = <1>;
+ gop-port-id = <2>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(eth2): eth2 {
+ interrupts = <ICU_GRP_NSR 41 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 45 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 49 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 53 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 57 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 127 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
+ "tx-cpu3", "rx-shared", "link";
+ port-id = <2>;
+ gop-port-id = <3>;
+ status = "disabled";
+ };
+ };
+
+ CP110_LABEL(comphy): phy at 120000 {
+ compatible = "marvell,comphy-cp110";
+ reg = <0x120000 0x6000>;
+ marvell,system-controller = <&CP110_LABEL(syscon0)>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ CP110_LABEL(comphy0): phy at 0 {
+ reg = <0>;
+ #phy-cells = <1>;
+ };
+
+ CP110_LABEL(comphy1): phy at 1 {
+ reg = <1>;
+ #phy-cells = <1>;
+ };
+
+ CP110_LABEL(comphy2): phy at 2 {
+ reg = <2>;
+ #phy-cells = <1>;
+ };
+
+ CP110_LABEL(comphy3): phy at 3 {
+ reg = <3>;
+ #phy-cells = <1>;
+ };
+
+ CP110_LABEL(comphy4): phy at 4 {
+ reg = <4>;
+ #phy-cells = <1>;
+ };
+
+ CP110_LABEL(comphy5): phy at 5 {
+ reg = <5>;
+ #phy-cells = <1>;
+ };
+ };
+
+ CP110_LABEL(mdio): mdio at 12a200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,orion-mdio";
+ reg = <0x12a200 0x10>;
+ clocks = <&CP110_LABEL(clk) 1 9>, <&CP110_LABEL(clk) 1 5>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(xmdio): mdio at 12a600 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "marvell,xmdio";
+ reg = <0x12a600 0x10>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(icu): interrupt-controller at 1e0000 {
+ compatible = "marvell,cp110-icu";
+ reg = <0x1e0000 0x10>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ msi-parent = <&gicp>;
+ };
+
+ CP110_LABEL(rtc): rtc at 284000 {
+ compatible = "marvell,armada-8k-rtc";
+ reg = <0x284000 0x20>, <0x284080 0x24>;
+ reg-names = "rtc", "rtc-soc";
+ interrupts = <ICU_GRP_NSR 77 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ CP110_LABEL(syscon0): system-controller at 440000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x440000 0x2000>;
+
+ CP110_LABEL(clk): clock {
+ compatible = "marvell,cp110-clock";
+ #clock-cells = <2>;
+ };
+
+ CP110_LABEL(gpio1): gpio at 100 {
+ compatible = "marvell,armada-8k-gpio";
+ offset = <0x100>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&CP110_LABEL(pinctrl) 0 0 32>;
+ interrupt-controller;
+ interrupts = <ICU_GRP_NSR 86 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 85 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 84 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 83 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(gpio2): gpio at 140 {
+ compatible = "marvell,armada-8k-gpio";
+ offset = <0x140>;
+ ngpios = <31>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&CP110_LABEL(pinctrl) 0 32 31>;
+ interrupt-controller;
+ interrupts = <ICU_GRP_NSR 82 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 81 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 80 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 79 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+ };
+
+ CP110_LABEL(usb3_0): usb3 at 500000 {
+ compatible = "marvell,armada-8k-xhci",
+ "generic-xhci";
+ reg = <0x500000 0x4000>;
+ dma-coherent;
+ interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CP110_LABEL(clk) 1 22>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(usb3_1): usb3 at 510000 {
+ compatible = "marvell,armada-8k-xhci",
+ "generic-xhci";
+ reg = <0x510000 0x4000>;
+ dma-coherent;
+ interrupts = <ICU_GRP_NSR 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CP110_LABEL(clk) 1 23>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(sata0): sata at 540000 {
+ compatible = "marvell,armada-8k-ahci",
+ "generic-ahci";
+ reg = <0x540000 0x30000>;
+ interrupts = <ICU_GRP_NSR 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CP110_LABEL(clk) 1 15>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(xor0): xor at 6a0000 {
+ compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+ reg = <0x6a0000 0x1000>, <0x6b0000 0x1000>;
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+ clocks = <&CP110_LABEL(clk) 1 8>;
+ };
+
+ CP110_LABEL(xor1): xor at 6c0000 {
+ compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+ reg = <0x6c0000 0x1000>, <0x6d0000 0x1000>;
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+ clocks = <&CP110_LABEL(clk) 1 7>;
+ };
+
+ CP110_LABEL(spi0): spi at 700600 {
+ compatible = "marvell,armada-380-spi";
+ reg = <0x700600 0x50>;
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ clocks = <&CP110_LABEL(clk) 1 21>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(spi1): spi at 700680 {
+ compatible = "marvell,armada-380-spi";
+ reg = <0x700680 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&CP110_LABEL(clk) 1 21>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(i2c0): i2c at 701000 {
+ compatible = "marvell,mv78230-i2c";
+ reg = <0x701000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <ICU_GRP_NSR 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CP110_LABEL(clk) 1 21>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(i2c1): i2c at 701100 {
+ compatible = "marvell,mv78230-i2c";
+ reg = <0x701100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <ICU_GRP_NSR 121 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CP110_LABEL(clk) 1 21>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(nand_controller): nand at 720000 {
+ /*
+ * Due to the limitation of the pins available
+ * this controller is only usable on the CPM
+ * for A7K and on the CPS for A8K.
+ */
+ compatible = "marvell,armada-8k-nand-controller",
+ "marvell,armada370-nand-controller";
+ reg = <0x720000 0x54>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <ICU_GRP_NSR 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CP110_LABEL(clk) 1 2>;
+ marvell,system-controller = <&CP110_LABEL(syscon0)>;
+ status = "disabled";
+ };
+
+ CP110_LABEL(trng): trng at 760000 {
+ compatible = "marvell,armada-8k-rng",
+ "inside-secure,safexcel-eip76";
+ reg = <0x760000 0x7d>;
+ interrupts = <ICU_GRP_NSR 95 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&CP110_LABEL(clk) 1 25>;
+ status = "okay";
+ };
+
+ CP110_LABEL(sdhci0): sdhci at 780000 {
+ compatible = "marvell,armada-cp110-sdhci";
+ reg = <0x780000 0x300>;
+ interrupts = <ICU_GRP_NSR 27 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "core";
+ clocks = <&CP110_LABEL(clk) 1 4>;
+ dma-coherent;
+ status = "disabled";
+ };
+
+ CP110_LABEL(crypto): crypto at 800000 {
+ compatible = "inside-secure,safexcel-eip197";
+ reg = <0x800000 0x200000>;
+ interrupts = <ICU_GRP_NSR 87 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 88 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 89 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 90 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 91 IRQ_TYPE_LEVEL_HIGH>,
+ <ICU_GRP_NSR 92 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mem", "ring0", "ring1",
+ "ring2", "ring3", "eip";
+ clocks = <&CP110_LABEL(clk) 1 26>;
+ dma-coherent;
+ };
+};
+
+CP110_LABEL(pcie0): pcie at CP110_PCIE0_BASE {
+ compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+ reg = <0 ADDRESSIFY(CP110_PCIE0_BASE) 0 0x10000>,
+ <0 CP110_PCIEx_CONF_BASE(0) 0 0x80000>;
+ reg-names = "ctrl", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+
+ bus-range = <0 0xff>;
+ ranges =
+ /* downstream I/O */
+ <0x81000000 0 CP110_PCIEx_IO_BASE(0) 0 CP110_PCIEx_IO_BASE(0) 0 0x10000
+ /* non-prefetchable memory */
+ 0x82000000 0 CP110_PCIEx_MEM_BASE(0) 0 CP110_PCIEx_MEM_BASE(0) 0 0xf00000>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &CP110_LABEL(icu) ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
+ num-lanes = <1>;
+ clocks = <&CP110_LABEL(clk) 1 13>;
+ status = "disabled";
+};
+
+CP110_LABEL(pcie1): pcie at CP110_PCIE1_BASE {
+ compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+ reg = <0 ADDRESSIFY(CP110_PCIE1_BASE) 0 0x10000>,
+ <0 CP110_PCIEx_CONF_BASE(1) 0 0x80000>;
+ reg-names = "ctrl", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+
+ bus-range = <0 0xff>;
+ ranges =
+ /* downstream I/O */
+ <0x81000000 0 CP110_PCIEx_IO_BASE(1) 0 CP110_PCIEx_IO_BASE(1) 0 0x10000
+ /* non-prefetchable memory */
+ 0x82000000 0 CP110_PCIEx_MEM_BASE(1) 0 CP110_PCIEx_MEM_BASE(1) 0 0xf00000>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &CP110_LABEL(icu) ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
+
+ num-lanes = <1>;
+ clocks = <&CP110_LABEL(clk) 1 11>;
+ status = "disabled";
+};
+
+CP110_LABEL(pcie2): pcie at CP110_PCIE2_BASE {
+ compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+ reg = <0 ADDRESSIFY(CP110_PCIE2_BASE) 0 0x10000>,
+ <0 CP110_PCIEx_CONF_BASE(2) 0 0x80000>;
+ reg-names = "ctrl", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+
+ bus-range = <0 0xff>;
+ ranges =
+ /* downstream I/O */
+ <0x81000000 0 CP110_PCIEx_IO_BASE(2) 0 CP110_PCIEx_IO_BASE(2) 0 0x10000
+ /* non-prefetchable memory */
+ 0x82000000 0 CP110_PCIEx_MEM_BASE(2) 0 CP110_PCIEx_MEM_BASE(2) 0 0xf00000>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &CP110_LABEL(icu) ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
+
+ num-lanes = <1>;
+ clocks = <&CP110_LABEL(clk) 1 12>;
+ status = "disabled";
+};
--
2.14.3
^ permalink raw reply related
* [PATCH 10/14] iio: adc: at91-sama5d2_adc: force trigger removal on module remove
From: Jonathan Cameron @ 2017-12-29 16:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513955241-10985-11-git-send-email-eugen.hristev@microchip.com>
On Fri, 22 Dec 2017 17:07:17 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> On module remove, if we do not call trigger remove, the trigger
> stays in the subsystem, and on further module insert, we will have
> multiple triggers, and the old one is not usable.
> Have to call the remove function on module remove to solve this.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
This needs more explanation. I can't see why the managed removal
isn't sufficient. On removal the dev should have gone away taking
the trigger with it.
If it isn't then it looks like a straight forward bug that needs fixing.
Jonathan
> ---
> drivers/iio/adc/at91-sama5d2_adc.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 4eff835..7b9febc 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -1180,6 +1180,9 @@ static int at91_adc_remove(struct platform_device *pdev)
> struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> struct at91_adc_state *st = iio_priv(indio_dev);
>
> + if (st->selected_trig->hw_trig)
> + devm_iio_trigger_unregister(&indio_dev->dev, st->trig);
> +
> iio_device_unregister(indio_dev);
>
> at91_adc_dma_disable(pdev);
^ permalink raw reply
* [PATCH 11/14] iio: adc: at91-sama5d2_adc: optimize scan index for diff channels
From: Jonathan Cameron @ 2017-12-29 16:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513955241-10985-12-git-send-email-eugen.hristev@microchip.com>
On Fri, 22 Dec 2017 17:07:18 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> Optimize the scan index for the differential channels. Before, it
> was single channel count + index of the first single channel
> number of the differential pair. (e.g. 11+0, +2, +4, etc.)
> Divide that number by two (since it's always even), and add it up
> as a scan index to have consecutive numbered channels in the
> index.
Why? This is odd as it stands, but that isn't a strong enough reason
to fix it.
This is making a userspace ABI change. We need a very strong
argument for why it is necessary and also why existing userspace
won't care.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
> drivers/iio/adc/at91-sama5d2_adc.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 7b9febc..9610393 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -209,7 +209,7 @@
> .channel = num, \
> .channel2 = num2, \
> .address = addr, \
> - .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT, \
> + .scan_index = (num >> 1) + AT91_SAMA5D2_SINGLE_CHAN_CNT,\
> .scan_type = { \
> .sign = 's', \
> .realbits = 12, \
^ permalink raw reply
* v4.15: camera problems on n900
From: Pavel Machek @ 2017-12-29 16:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171229093855.hz44vpssb5mufzop@valkosipuli.retiisi.org.uk>
On Fri 2017-12-29 11:38:55, Sakari Ailus wrote:
> On Thu, Dec 28, 2017 at 09:24:53PM +0100, Pavel Machek wrote:
> > On Wed 2017-12-27 23:17:19, Sakari Ailus wrote:
> > > On Wed, Dec 27, 2017 at 10:05:43PM +0100, Pavel Machek wrote:
> > > > Hi!
> > > >
> > > > In v4.14, back camera on N900 works. On v4.15-rc1.. it works for few
> > > > seconds, but then I get repeated oopses.
> > > >
> > > > On v4.15-rc0.5 (commit ed30b147e1f6e396e70a52dbb6c7d66befedd786),
> > > > camera does not start.
> > > >
> > > > Any ideas what might be wrong there?
> > >
> > > What kind of oopses do you get?
> >
> > Hmm. bisect pointed to commit that can't be responsible.... Ideas
> > welcome.
>
> Hi Pavel,
>
> I tested N9 and capture appears to be working from the CSI-2 receiver
> (media tree master, i.e. v4.15-rc3 now).
>
> Which pipeline did you use?
I'm using the "main" sensor (5MPx) and am using capture (not preview)
pipeline.
I tested linux-next in the meantime, and that one seems to
work. (Which is strange, I believe it oopsed before. Perhaps something
random?) With linux-next working, it should not be hardto figure out
what is going on.
Thanks,
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20171229/8f7efadb/attachment.sig>
^ permalink raw reply
* [PATCH v2 26/36] KVM: arm64: Defer saving/restoring system registers to vcpu load/put on VHE
From: Christoffer Dall @ 2017-12-29 16:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c45eaebe-57a1-7737-c515-111d497dd06e@arm.com>
On Mon, Dec 11, 2017 at 01:20:03PM +0000, Marc Zyngier wrote:
> On 07/12/17 17:06, Christoffer Dall wrote:
> > Some system registers do not affect the host kernel's execution and can
> > therefore be loaded when we are about to run a VCPU and we don't have to
> > restore the host state to the hardware before the time when we are
> > actually about to return to userspace or schedule out the VCPU thread.
> >
> > The EL1 system registers and the userspace state registers, which only
> > affect EL0 execution, do not affect the host kernel's execution.
> >
> > The 32-bit system registers are not used by a VHE host kernel and
> > therefore don't need to be saved/restored on every entry/exit to/from
> > the guest, but can be deferred to vcpu_load and vcpu_put, respectively.
>
> Note that they are not used by the !VHE host kernel either, and I
> believe they could be deferred too, although that would imply a round
> trip to HYP to save/restore them. We already have such a hook there when
> configuring ICH_VMCR_EL2, so we may not need much of a new infrastructure.
>
> What do you think?
>
This turned out to be a bit of a mess. We can do this, but it conflicts
with the idea of hiding the sysregs_loaded_on_cpu handling based on
classifying a system register as deferrable or immediate.
What we'd need to do is to add a separate flag for the system registers
which are deferred on !VHE as well as VHE, for example
sysregs32_loaded_on_cpu (or something more generic like
nvhe_vhe_sysregs_loaded_on_cpu - in lack of a better name). We'd then
have to duplicate the DEFERRED macro for this other category of sysregs,
which checks our new flag instead of sysregs_loaded_on_cpu, and we'd
have to map all the accessors in Hyp, and do kvm_call_hyp() around all
the accessors (which could hurt normal performance) or expand the
deferred macros to output two functions, where the non-hyp calls into
the hyp one if the system register is loaded on the cpu.
Of course, it's arguable that all this is not needed because the 32-bit
system registers are not actually used yet for emulation while the state
could be loaded on the cpu, so it doesn't matter, but then we're back to
my original approach where all the code just has to know the state of a
register and when modifying KVM code we have to think carefully about
that.
Basically, I don't think the complexity is worth the effort given that
this only optimizes 32-bit guests, and I think we should just leave this
part out.
Thoughts?
Thanks,
-Christoffer
^ permalink raw reply
* [PATCH 12/14] iio: adc: at91-sama5d2_adc: support for position and pressure channels
From: Jonathan Cameron @ 2017-12-29 17:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513955241-10985-13-git-send-email-eugen.hristev@microchip.com>
On Fri, 22 Dec 2017 17:07:19 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> The ADC IP supports position and pressure measurements for a touchpad
> connected on channels 0,1,2,3 for a 4-wire touchscreen with pressure
> measurement support.
> Using the inkern API, a driver can request a trigger and read the
> channel values from the ADC.
> The implementation provides a trigger named "touch" which can be
> connected to a consumer driver.
> Once a driver connects and attaches a pollfunc to this trigger, the
> configure trigger callback is called, and then the ADC driver will
> initialize pad measurement.
> First step is to enable touchscreen 4wire support and enable
> pen detect IRQ.
> Once a pen is detected, a periodic trigger is setup to trigger every
> 2 ms (e.g.) and sample the resistive touchscreen values. The trigger poll
> is called, and the consumer driver is then woke up, and it can read the
> respective channels for the values : X, and Y for position and pressure
> channel.
> Because only one trigger can be active in hardware in the same time,
> while touching the pad, the ADC will block any attempt to use the
> triggered buffer. Same, conversions using the software trigger are also
> impossible (since the periodic trigger is setup).
> If some driver wants to attach while the trigger is in use, it will
> also fail.
> Once the pen is not detected anymore, the trigger is free for use (hardware
> or software trigger, with or without DMA).
> Channels 0,1,2 and 3 are unavailable if a touchscreen is enabled.
>
> Some parts of this patch are based on initial original work by
> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
>
OK, so comments inline.
What I'm missing currently though is an explanation of why the slightly
more standard arrangement of using a callback buffer doesn't work here.
The only addition I think you need to do that is to allow a consumer to
request a particular trigger. I also think some of the other provisions
could be handled using standard features and slightly reducing the flexibility.
I don't know for example if it's useful to allow other channels to be
read when touch is not in progress or not.
So restrictions:
1. Touch screen channels can only be read when touch is enabled.
- use the available_scan_masks to control this. Or the callback that lets
you do the same dynamically.
2. You need to push these channels to your consumer driver.
- register a callback buffer rather than jumping through the hoops to
insert your own pollfunc. That will call a function in your
consumer, providing the data from the 3 channels directly.
3. You need to make sure it is using the right driver. For that you
will I think need a new interface.
Various other comments inline. I may well be missing something as this is
a fair bit of complex code to read - if so then next version should have
a clear cover letter describing why this more standard approach can't be
used.
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
> drivers/iio/adc/at91-sama5d2_adc.c | 455 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 446 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 9610393..79eb197 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -102,14 +102,26 @@
> #define AT91_SAMA5D2_LCDR 0x20
> /* Interrupt Enable Register */
> #define AT91_SAMA5D2_IER 0x24
> +/* Interrupt Enable Register - TS X measurement ready */
> +#define AT91_SAMA5D2_IER_XRDY BIT(20)
> +/* Interrupt Enable Register - TS Y measurement ready */
> +#define AT91_SAMA5D2_IER_YRDY BIT(21)
> +/* Interrupt Enable Register - TS pressure measurement ready */
> +#define AT91_SAMA5D2_IER_PRDY BIT(22)
> /* Interrupt Enable Register - general overrun error */
> #define AT91_SAMA5D2_IER_GOVRE BIT(25)
> +/* Interrupt Enable Register - Pen detect */
> +#define AT91_SAMA5D2_IER_PEN BIT(29)
> +/* Interrupt Enable Register - No pen detect */
> +#define AT91_SAMA5D2_IER_NOPEN BIT(30)
> /* Interrupt Disable Register */
> #define AT91_SAMA5D2_IDR 0x28
> /* Interrupt Mask Register */
> #define AT91_SAMA5D2_IMR 0x2c
> /* Interrupt Status Register */
> #define AT91_SAMA5D2_ISR 0x30
> +/* Interrupt Status Register - Pen touching sense status */
> +#define AT91_SAMA5D2_ISR_PENS BIT(31)
> /* Last Channel Trigger Mode Register */
> #define AT91_SAMA5D2_LCTMR 0x34
> /* Last Channel Compare Window Register */
> @@ -131,8 +143,37 @@
> #define AT91_SAMA5D2_CDR0 0x50
> /* Analog Control Register */
> #define AT91_SAMA5D2_ACR 0x94
> +/* Analog Control Register - Pen detect sensitivity mask */
> +#define AT91_SAMA5D2_ACR_PENDETSENS_MASK GENMASK(0, 1)
> /* Touchscreen Mode Register */
> #define AT91_SAMA5D2_TSMR 0xb0
> +/* Touchscreen Mode Register - No touch mode */
> +#define AT91_SAMA5D2_TSMR_TSMODE_NONE 0
> +/* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> +#define AT91_SAMA5D2_TSMR_TSMODE_4WIRE_NO_PRESS 1
> +/* Touchscreen Mode Register - 4 wire screen, pressure measurement */
> +#define AT91_SAMA5D2_TSMR_TSMODE_4WIRE_PRESS 2
> +/* Touchscreen Mode Register - 5 wire screen */
> +#define AT91_SAMA5D2_TSMR_TSMODE_5WIRE 3
> +/* Touchscreen Mode Register - Average samples mask */
> +#define AT91_SAMA5D2_TSMR_TSAV_MASK (3 << 4)
> +/* Touchscreen Mode Register - Average samples */
> +#define AT91_SAMA5D2_TSMR_TSAV(x) ((x) << 4)
> +/* Touchscreen Mode Register - Touch/trigger frequency ratio mask */
> +#define AT91_SAMA5D2_TSMR_TSFREQ_MASK (0xf << 8)
> +/* Touchscreen Mode Register - Touch/trigger freqency ratio */
> +#define AT91_SAMA5D2_TSMR_TSFREQ(x) ((x) << 8)
> +/* Touchscreen Mode Register - Pen Debounce Time mask */
> +#define AT91_SAMA5D2_TSMR_PENDBC_MASK (0xf << 28)
> +/* Touchscreen Mode Register - Pen Debounce Time */
> +#define AT91_SAMA5D2_TSMR_PENDBC(x) ((x) << 28)
> +/* Touchscreen Mode Register - No DMA for touch measurements */
> +#define AT91_SAMA5D2_TSMR_NOTSDMA BIT(22)
> +/* Touchscreen Mode Register - Disable pen detection */
> +#define AT91_SAMA5D2_TSMR_PENDET_DIS (0 << 24)
> +/* Touchscreen Mode Register - Enable pen detection */
> +#define AT91_SAMA5D2_TSMR_PENDET_ENA BIT(24)
> +
> /* Touchscreen X Position Register */
> #define AT91_SAMA5D2_XPOSR 0xb4
> /* Touchscreen Y Position Register */
> @@ -151,7 +192,12 @@
> #define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL 2
> /* Trigger Mode external trigger any edge */
> #define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY 3
> -
> +/* Trigger Mode internal periodic */
> +#define AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC 5
> +/* Trigger Mode - trigger period mask */
> +#define AT91_SAMA5D2_TRGR_TRGPER_MASK (0xffff << 16)
> +/* Trigger Mode - trigger period */
> +#define AT91_SAMA5D2_TRGR_TRGPER(x) ((x) << 16)
> /* Correction Select Register */
> #define AT91_SAMA5D2_COSR 0xd0
> /* Correction Value Register */
> @@ -169,6 +215,21 @@
> #define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> #define AT91_SAMA5D2_DIFF_CHAN_CNT 6
>
> +#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> + AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> +
> +#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_TIMESTAMP_CHAN_IDX + 1)
> +#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> +#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> +
> +#define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */
These all need the AT91_SAMA5D2 prefix.
> +#define TOUCH_PEN_DETECT_DEBOUNCE_US 200
> +
> +#define XYZ_MASK GENMASK(11, 0)
> +
> +#define MAX_POS_BITS 12
> +
> +#define AT91_ADC_TOUCH_TRIG_SHORTNAME "touch"
> /*
> * Maximum number of bytes to hold conversion from all channels
> * without the timestamp.
> @@ -222,6 +283,37 @@
> .indexed = 1, \
> }
>
> +#define AT91_SAMA5D2_CHAN_TOUCH(num, name, mod) \
> + { \
> + .type = IIO_POSITION, \
> + .modified = 1, \
> + .channel = num, \
> + .channel2 = mod, \
> + .scan_index = num, \
> + .scan_type = { \
> + .sign = 'u', \
> + .realbits = 12, \
> + .storagebits = 16, \
> + }, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
> + .datasheet_name = name, \
> + }
> +#define AT91_SAMA5D2_CHAN_PRESSURE(num, name) \
> + { \
> + .type = IIO_PRESSURE, \
> + .channel = num, \
> + .scan_index = num, \
> + .scan_type = { \
> + .sign = 'u', \
> + .realbits = 12, \
> + .storagebits = 16, \
> + }, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
> + .datasheet_name = name, \
> + }
> +
> #define at91_adc_readl(st, reg) readl_relaxed(st->base + reg)
> #define at91_adc_writel(st, reg, val) writel_relaxed(val, st->base + reg)
>
> @@ -239,6 +331,20 @@ struct at91_adc_trigger {
> };
>
> /**
> + * at91_adc_touch - at91-sama5d2 touchscreen information struct
> + * @trig: hold the start timestamp of dma operation
> + * @sample_period_val: the value for periodic trigger interval
> + * @touching: is the pen touching the screen or not
> + * @x_pos: temporary placeholder for pressure computation
> + */
> +struct at91_adc_touch {
> + struct iio_trigger *trig;
> + u16 sample_period_val;
> + bool touching;
> + u32 x_pos;
> +};
> +
> +/**
> * at91_adc_dma - at91-sama5d2 dma information struct
> * @dma_chan: the dma channel acquired
> * @rx_buf: dma coherent allocated area
> @@ -267,18 +373,22 @@ struct at91_adc_state {
> struct regulator *reg;
> struct regulator *vref;
> int vref_uv;
> + unsigned int current_sample_rate;
> struct iio_trigger *trig;
> const struct at91_adc_trigger *selected_trig;
> const struct iio_chan_spec *chan;
> bool conversion_done;
> u32 conversion_value;
> + bool touch_requested;
> struct at91_adc_soc_info soc_info;
> wait_queue_head_t wq_data_available;
> struct at91_adc_dma dma_st;
> + struct at91_adc_touch touch_st;
> u16 buffer[AT91_BUFFER_MAX_HWORDS];
> /*
> * lock to prevent concurrent 'single conversion' requests through
> - * sysfs.
> + * sysfs. Also protects when enabling or disabling touchscreen
> + * producer mode and checking if this mode is enabled or not.
> */
> struct mutex lock;
> };
> @@ -310,6 +420,7 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
> },
> };
>
> +/* channel order is not subject to change. inkern consumers rely on this */
> static const struct iio_chan_spec at91_adc_channels[] = {
> AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> @@ -329,10 +440,103 @@ static const struct iio_chan_spec at91_adc_channels[] = {
> AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> - IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_SINGLE_CHAN_CNT
> - + AT91_SAMA5D2_DIFF_CHAN_CNT + 1),
> + IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> + AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> + AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> + AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> };
>
> +static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> +{
> + u32 clk_khz = st->current_sample_rate / 1000;
> + int i = 0;
> + u16 pendbc;
> + u32 tsmr, acr;
> +
> + if (!state) {
> + /* disabling touch IRQs and setting mode to no touch enabled */
> + at91_adc_writel(st, AT91_SAMA5D2_IDR,
> + AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
> + at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
> + return 0;
> + }
> + /*
> + * debounce time is in microseconds, we need it in milliseconds to
> + * multiply with kilohertz, so, divide by 1000, but after the multiply.
> + * round up to make sure pendbc is at least 1
> + */
> + pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * clk_khz / 1000, 1);
> +
> + /* get the required exponent */
> + while (pendbc >> i++)
> + ;
This is related to the first 0? There are cleaner ways of doing this
with ffs and friends.
> +
> + pendbc = i;
> +
> + tsmr = AT91_SAMA5D2_TSMR_TSMODE_4WIRE_PRESS;
> +
> + tsmr |= AT91_SAMA5D2_TSMR_TSAV(1) & AT91_SAMA5D2_TSMR_TSAV_MASK;
> + tsmr |= AT91_SAMA5D2_TSMR_PENDBC(pendbc) &
> + AT91_SAMA5D2_TSMR_PENDBC_MASK;
> + tsmr |= AT91_SAMA5D2_TSMR_NOTSDMA;
> + tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
> + tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(1) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
> +
> + at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
> +
> + acr = at91_adc_readl(st, AT91_SAMA5D2_ACR);
> + acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> + acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> + at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
> +
> + /* Sample Period Time = (TRGPER + 1) / ADCClock */
> + st->touch_st.sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US *
> + clk_khz / 1000) - 1, 1);
> + /* enable pen detect IRQ */
> + at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +
> + return 0;
> +}
> +
> +static int at91_adc_touch_trigger_validate_device(struct iio_trigger *trig,
> + struct iio_dev *indio_dev)
> +{
> + /* the touch trigger cannot be used with a buffer */
> + return -EBUSY;
> +}
> +
> +static int at91_adc_configure_touch_trigger(struct iio_trigger *trig,
> + bool state)
> +{
> + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> + struct at91_adc_state *st = iio_priv(indio_dev);
> + int ret = 0;
> +
> + /*
> + * If we configure this with the IRQ enabled, the pen detected IRQ
> + * might fire before we finish setting all up, and the IRQ handler
> + * might misbehave. Better to reenable the IRQ after we are done
> + */
> + disable_irq_nosync(st->irq);
> +
> + mutex_lock(&st->lock);
> + if (state) {
> + ret = iio_buffer_enabled(indio_dev);
> + if (ret) {
> + dev_dbg(&indio_dev->dev, "trigger is currently in use\n");
> + ret = -EBUSY;
> + goto configure_touch_unlock_exit;
> + }
> + }
> + at91_adc_configure_touch(st, state);
> + st->touch_requested = state;
> +
> +configure_touch_unlock_exit:
> + enable_irq(st->irq);
> + mutex_unlock(&st->lock);
> + return ret;
> +}
> +
> static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> {
> struct iio_dev *indio = iio_trigger_get_drvdata(trig);
> @@ -390,12 +594,27 @@ static int at91_adc_reenable_trigger(struct iio_trigger *trig)
> return 0;
> }
>
> +static int at91_adc_reenable_touch_trigger(struct iio_trigger *trig)
> +{
> + struct iio_dev *indio = iio_trigger_get_drvdata(trig);
> + struct at91_adc_state *st = iio_priv(indio);
> +
> + enable_irq(st->irq);
> +
> + return 0;
> +}
> static const struct iio_trigger_ops at91_adc_trigger_ops = {
> .set_trigger_state = &at91_adc_configure_trigger,
> .try_reenable = &at91_adc_reenable_trigger,
> .validate_device = iio_trigger_validate_own_device,
> };
>
> +static const struct iio_trigger_ops at91_adc_touch_trigger_ops = {
> + .set_trigger_state = &at91_adc_configure_touch_trigger,
> + .try_reenable = &at91_adc_reenable_touch_trigger,
> + .validate_device = &at91_adc_touch_trigger_validate_device,
> +};
> +
> static int at91_adc_dma_size_done(struct at91_adc_state *st)
> {
> struct dma_tx_state state;
> @@ -490,6 +709,23 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
> return 0;
> }
>
> +static int at91_adc_buffer_preenable(struct iio_dev *indio_dev)
> +{
> + struct at91_adc_state *st = iio_priv(indio_dev);
> + int ret;
> +
> + /* have to make sure nobody is requesting the trigger right now */
This needs some more explanation as I don't totally follow what this
is designed to protect against.
Realistically a device is only useful if it has one trigger at a time
feeding a valid set of channels to however many consumers (whether
in the driver or not).
> + mutex_lock(&st->lock);
> + ret = st->touch_requested;
> + mutex_unlock(&st->lock);
> +
> + /*
> + * if the trigger is used by the touchscreen,
> + * we must return an error
> + */
> + return ret ? -EBUSY : 0;
> +}
> +
> static int at91_adc_buffer_postenable(struct iio_dev *indio_dev)
> {
> int ret;
> @@ -538,6 +774,7 @@ static int at91_adc_buffer_predisable(struct iio_dev *indio_dev)
> }
>
> static const struct iio_buffer_setup_ops at91_buffer_setup_ops = {
> + .preenable = &at91_adc_buffer_preenable,
> .postenable = &at91_adc_buffer_postenable,
> .predisable = &at91_adc_buffer_predisable,
> };
> @@ -555,7 +792,11 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio,
>
> trig->dev.parent = indio->dev.parent;
> iio_trigger_set_drvdata(trig, indio);
> - trig->ops = &at91_adc_trigger_ops;
> +
> + if (strcmp(trigger_name, AT91_ADC_TOUCH_TRIG_SHORTNAME))
Pass this is as a parameter to the function and avoid the strcmp nastiness.
> + trig->ops = &at91_adc_trigger_ops;
> + else
> + trig->ops = &at91_adc_touch_trigger_ops;
>
> ret = devm_iio_trigger_register(&indio->dev, trig);
> if (ret)
> @@ -571,7 +812,16 @@ static int at91_adc_trigger_init(struct iio_dev *indio)
> st->trig = at91_adc_allocate_trigger(indio, st->selected_trig->name);
> if (IS_ERR(st->trig)) {
> dev_err(&indio->dev,
> - "could not allocate trigger\n");
> + "could not allocate trigger %s\n",
> + st->selected_trig->name);
> + return PTR_ERR(st->trig);
> + }
> +
> + st->touch_st.trig = at91_adc_allocate_trigger(indio,
> + AT91_ADC_TOUCH_TRIG_SHORTNAME);
> + if (IS_ERR(st->trig)) {
> + dev_err(&indio->dev, "could not allocate trigger"
> + AT91_ADC_TOUCH_TRIG_SHORTNAME "\n");
> return PTR_ERR(st->trig);
> }
>
> @@ -703,6 +953,8 @@ static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq)
>
> dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
> freq, startup, prescal);
> +
> + st->current_sample_rate = freq;
> }
>
> static unsigned at91_adc_get_sample_freq(struct at91_adc_state *st)
> @@ -718,23 +970,77 @@ static unsigned at91_adc_get_sample_freq(struct at91_adc_state *st)
> return f_adc;
> }
>
> +static irqreturn_t at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
> +{
> + at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
> + at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
> + AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> + AT91_SAMA5D2_IER_PRDY);
> + at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> + AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> + AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
> + st->touch_st.touching = true;
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t at91_adc_no_pen_detect_interrupt(struct at91_adc_state *st)
> +{
> + at91_adc_writel(st, AT91_SAMA5D2_TRGR, 0);
> + at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
> + AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> + AT91_SAMA5D2_IER_PRDY);
> + st->touch_st.touching = false;
Hmm. I think we are unfortunately racing here. There is nothing preventing
this running concurrently with the read_raw calls that check the same variable.
If this is fine (because we will always get valid data anyway (if stale)
then a comment is needed to explain that.
> +
> + disable_irq_nosync(st->irq);
> + iio_trigger_poll(st->touch_st.trig);
Comment to explain why a poll here is fine, but not on the pen on would be
good (I can guess but better to state it!)
> +
> + at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +
> + return IRQ_HANDLED;
> +}
> +
> static irqreturn_t at91_adc_interrupt(int irq, void *private)
> {
> struct iio_dev *indio = private;
> struct at91_adc_state *st = iio_priv(indio);
> u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
> + u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> + AT91_SAMA5D2_IER_PRDY;
>
> if (!(status & imr))
> return IRQ_NONE;
>
> - if (iio_buffer_enabled(indio) && !st->dma_st.dma_chan) {
> + if (st->touch_requested && (status & AT91_SAMA5D2_IER_PEN)) {
> + /* pen detected IRQ */
> + return at91_adc_pen_detect_interrupt(st);
> + } else if (st->touch_requested && (status & AT91_SAMA5D2_IER_NOPEN)) {
> + /* nopen detected IRQ */
> + return at91_adc_no_pen_detect_interrupt(st);
> + } else if (st->touch_requested && (status & AT91_SAMA5D2_ISR_PENS) &&
> + ((status & rdy_mask) == rdy_mask)) {
> + /* periodic trigger IRQ - during pen sense */
> + disable_irq_nosync(irq);
> + iio_trigger_poll(st->touch_st.trig);
> + } else if ((st->touch_requested && (status & AT91_SAMA5D2_ISR_PENS))) {
> + /*
> + * touching, but the measurements are not ready yet.
> + * read and ignore.
> + */
> + status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> + status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> + status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> + } else if (iio_buffer_enabled(indio) && !st->dma_st.dma_chan) {
> + /* buffered trigger without DMA */
> disable_irq_nosync(irq);
> iio_trigger_poll(indio->trig);
> } else if (iio_buffer_enabled(indio) && st->dma_st.dma_chan) {
> + /* buffered trigger with DMA - should not happen */
> disable_irq_nosync(irq);
> WARN(true, "Unexpected irq occurred\n");
> } else if (!iio_buffer_enabled(indio)) {
> + /* software requested conversion */
> st->conversion_value = at91_adc_readl(st, st->chan->address);
> st->conversion_done = true;
> wake_up_interruptible(&st->wq_data_available);
> @@ -742,6 +1048,96 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> return IRQ_HANDLED;
> }
>
> +static u32 at91_adc_touch_x_pos(struct at91_adc_state *st)
> +{
> + u32 xscale, val;
> + u32 x, xpos;
> +
> + /* x position = (x / xscale) * max, max = 2^MAX_POS_BITS - 1 */
> + val = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> + if (!val)
> + dev_dbg(&iio_priv_to_dev(st)->dev, "x_pos is 0\n");
> +
> + xpos = val & XYZ_MASK;
> + x = (xpos << MAX_POS_BITS) - xpos;
> + xscale = (val >> 16) & XYZ_MASK;
> + if (xscale == 0) {
> + dev_err(&iio_priv_to_dev(st)->dev, "xscale is 0\n");
> + return 0;
> + }
> + x /= xscale;
> + st->touch_st.x_pos = x;
> +
> + return x;
> +}
> +
> +static u32 at91_adc_touch_y_pos(struct at91_adc_state *st)
> +{
> + u32 yscale, val;
> + u32 y, ypos;
> +
> + /* y position = (y / yscale) * max, max = 2^MAX_POS_BITS - 1 */
> + val = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> + ypos = val & XYZ_MASK;
> + y = (ypos << MAX_POS_BITS) - ypos;
> + yscale = (val >> 16) & XYZ_MASK;
> +
> + if (yscale == 0)
> + return 0;
> +
> + y /= yscale;
> +
> + return y;
> +}
> +
> +static u32 at91_adc_touch_pressure(struct at91_adc_state *st)
> +{
> + u32 val, z1, z2;
> + u32 pres;
> + u32 rxp = 1;
> + u32 factor = 1000;
> +
> + /* calculate the pressure */
> + val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> + z1 = val & XYZ_MASK;
XYZ_MASK seems oddly named given what this seems to be doing...
> + z2 = (val >> 16) & XYZ_MASK;
> +
> + if (z1 != 0)
> + pres = rxp * (st->touch_st.x_pos * factor / 1024) *
> + (z2 * factor / z1 - factor) /
> + factor;
> + else
> + pres = 0xFFFFFFFF; /* no pen contact */
> +
> + return pres;
> +}
> +
> +static int at91_adc_read_position(struct at91_adc_state *st, int chan, int *val)
> +{
> + if (!st->touch_st.touching)
> + return -ENODATA;
> + if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
> + *val = at91_adc_touch_x_pos(st);
> + else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
> + *val = at91_adc_touch_y_pos(st);
> + else
> + return -ENODATA;
> +
> + return IIO_VAL_INT;
> +}
> +
> +static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, int *val)
> +{
> + if (!st->touch_st.touching)
> + return -ENODATA;
> + if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
General code flow simpler if you check error first
if (chan != AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
return -ENODATA;
*val =...
> + *val = at91_adc_touch_pressure(st);
> + else
> + return -ENODATA;
> +
> + return IIO_VAL_INT;
> +}
> +
> static int at91_adc_read_raw(struct iio_dev *indio_dev,
> struct iio_chan_spec const *chan,
> int *val, int *val2, long mask)
> @@ -752,11 +1148,38 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev,
>
> switch (mask) {
> case IIO_CHAN_INFO_RAW:
> + mutex_lock(&st->lock);
> +
> + if (chan->type == IIO_POSITION) {
Switch or else if as only one is true at a time.
Hmm. So you allow sysfs reads of these channels if touch in progress.
Do we actually have a use for this? Seems we could have simpler code
by just not providing direct reads for them if not.
> + ret = at91_adc_read_position(st, chan->channel, val);
> + mutex_unlock(&st->lock);
> + return ret;
> + }
> + if (chan->type == IIO_PRESSURE) {
> + ret = at91_adc_read_pressure(st, chan->channel, val);
> + mutex_unlock(&st->lock);
> + return ret;
> + }
> + /* if we using touch, channels 0, 1, 2, 3 are unavailable */
> + if (st->touch_requested && chan->channel <= 3) {
> + mutex_unlock(&st->lock);
> + return -EBUSY;
> + }
> + /*
> + * if we have the periodic trigger set up, we can't use
> + * software trigger either.
> + */
> + if (st->touch_st.touching) {
> + mutex_unlock(&st->lock);
> + return -ENODATA;
> + }
> +
> /* we cannot use software trigger if hw trigger enabled */
> ret = iio_device_claim_direct_mode(indio_dev);
> - if (ret)
> + if (ret) {
> + mutex_unlock(&st->lock);
> return ret;
> - mutex_lock(&st->lock);
> + }
>
> st->chan = chan;
>
> @@ -785,6 +1208,11 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev,
>
> at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
> at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> + /*
> + * It is possible that after this conversion, we reuse these
> + * channels for the touchscreen. So, reset the COR now.
> + */
> + at91_adc_writel(st, AT91_SAMA5D2_COR, 0);
>
> /* Needed to ACK the DRDY interruption */
> at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> @@ -1180,6 +1608,10 @@ static int at91_adc_remove(struct platform_device *pdev)
> struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> struct at91_adc_state *st = iio_priv(indio_dev);
>
> + mutex_lock(&st->lock);
> + devm_iio_trigger_unregister(&indio_dev->dev, st->touch_st.trig);
As before this needs detailed explanation. It should not be necessary.
> + mutex_unlock(&st->lock);
> +
> if (st->selected_trig->hw_trig)
> devm_iio_trigger_unregister(&indio_dev->dev, st->trig);
>
> @@ -1245,6 +1677,11 @@ static __maybe_unused int at91_adc_resume(struct device *dev)
> if (iio_buffer_enabled(indio_dev))
> at91_adc_configure_trigger(st->trig, true);
>
> + mutex_lock(&st->lock);
> + if (st->touch_requested)
> + at91_adc_configure_touch_trigger(st->touch_st.trig, true);
> + mutex_unlock(&st->lock);
> +
> return 0;
>
> vref_disable_resume:
^ permalink raw reply
* [PATCH 13/14] input: touchscreen: sama5d2_rts: SAMA5D2 Resistive touchscreen driver
From: Jonathan Cameron @ 2017-12-29 17:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513955241-10985-14-git-send-email-eugen.hristev@microchip.com>
On Fri, 22 Dec 2017 17:07:20 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> This is the implementation of the Microchip SAMA5D2 SOC resistive
> touchscreen driver.
> The driver registers an input device and connects to the give IIO device
> from devicetree. It requires an IIO trigger (acting as a consumer) and
> three IIO channels : one for X position, one for Y position and one
> for pressure.
> It the reports the values to the input subsystem.
>
> Some parts of this driver are based on the initial original work by
> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
I've suggested some difference in implementation, but this is very nearly
a generic resistive touch screen driver which is rather nice.
It does use somewhat magic trigger which is effectively a filtered
periodic trigger (only fires when touch has occurred) which would not
be particularly hard to implement in other resistive touch screen ADCs.
I'm not totally sure that is a strong requirement though - any periodic
trigger would work.
Anyhow, the big stuff to my mind is whether we can use the buffer_cb
code to do this. I originally wrote that for an accelerometer to input
bridge driver (which I never got around to finishing upstreaming). It's
existing usecases are rather esoteric but it should work here I think.
Jonathan
> ---
> drivers/input/touchscreen/Kconfig | 13 ++
> drivers/input/touchscreen/Makefile | 1 +
> drivers/input/touchscreen/sama5d2_rts.c | 287 ++++++++++++++++++++++++++++++++
> 3 files changed, 301 insertions(+)
> create mode 100644 drivers/input/touchscreen/sama5d2_rts.c
>
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 64b30fe..db8f541 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -126,6 +126,19 @@ config TOUCHSCREEN_ATMEL_MXT_T37
> Say Y here if you want support to output data from the T37
> Diagnostic Data object using a V4L device.
>
> +config TOUCHSCREEN_SAMA5D2
> + tristate "Microchip SAMA5D2 resistive touchscreen support"
> + depends on ARCH_AT91
> + depends on AT91_SAMA5D2_ADC
> + help
> + Say Y here if you have 4-wire touchscreen connected
> + to ADC Controller on your SAMA5D2 Microchip SoC.
> +
> + If unsure, say N.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called sama5d2_rts.
> +
> config TOUCHSCREEN_AUO_PIXCIR
> tristate "AUO in-cell touchscreen using Pixcir ICs"
> depends on I2C
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index 850c156..9a2772e 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
> obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
> obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
> obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
> +obj-$(CONFIG_TOUCHSCREEN_SAMA5D2) += sama5d2_rts.o
> obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
> obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
> obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
> diff --git a/drivers/input/touchscreen/sama5d2_rts.c b/drivers/input/touchscreen/sama5d2_rts.c
> new file mode 100644
> index 0000000..e2ae413
> --- /dev/null
> +++ b/drivers/input/touchscreen/sama5d2_rts.c
> @@ -0,0 +1,287 @@
> +/*
> + * Microchip resistive touchscreen (RTS) driver for SAMA5D2.
> + *
> + * Copyright (C) 2017 Microchip Technology,
> + * Author: Eugen Hristev <eugen.hristev@microchip.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0
> + */
> +#include <linux/input.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/iio/consumer.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +
> +#define DRIVER_NAME "sama5d2_rts"
> +#define MAX_POS_MASK GENMASK(11, 0)
> +#define AT91_RTS_DEFAULT_PRESSURE_THRESHOLD 10000
> +
> +/**
> + * at91_rts - at91 resistive touchscreen information struct
> + * @input: the input device structure that we register
> + * @chan_x: X channel to IIO device to get position on X axis
> + * @chan_y: Y channel to IIO device to get position on Y axis
> + * @chan_pressure: pressure channel to IIO device to get pressure
> + * @trig: trigger to IIO device to register to for polling
> + * @rts_pf: pollfunc for the trigger to be called by IIO dev
> + * @pressure_threshold: number representing the threshold for the pressure
> + * @adc_connected: to know if adc device is connected
> + * @workq: to defer computations to this work queue for reporting
> + */
> +struct at91_rts {
> + struct input_dev *input;
> + struct iio_channel *chan_x, *chan_y, *chan_pressure;
> + struct iio_trigger *trig;
> + struct iio_poll_func *rts_pf;
> + u32 pressure_threshold;
> + bool adc_connected;
> + struct work_struct workq;
> +};
> +
> +static irqreturn_t at91_rts_trigger_handler(int irq, void *p)
> +{
> + struct at91_rts *st = ((struct iio_poll_func *)p)->p;
> +
> + schedule_work(&st->workq);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static void at91_rts_workq_handler(struct work_struct *workq)
> +{
> + struct at91_rts *st = container_of(workq, struct at91_rts, workq);
> + unsigned int x, y, press;
> + int ret;
> +
If we were instead to use a callback buffer this would all be
in the ADC driver as a simple 3 element channel scan.
> + /* read the channels, if all good, report touch */
> + ret = iio_read_channel_raw(st->chan_x, &x);
> + if (ret < 0)
> + goto at91_rts_workq_handler_end_touch;
> +
> + ret = iio_read_channel_raw(st->chan_y, &y);
> + if (ret < 0)
> + goto at91_rts_workq_handler_end_touch;
> +
> + ret = iio_read_channel_raw(st->chan_pressure, &press);
> + if (ret < 0)
> + goto at91_rts_workq_handler_end_touch;
> +
At this point our callback would be called and provided the above data.
> + /* if pressure too low, don't report */
> + if (press > st->pressure_threshold)
> + goto at91_rts_workq_handler_exit;
> +
> + input_report_abs(st->input, ABS_X, x);
> + input_report_abs(st->input, ABS_Y, y);
> + input_report_abs(st->input, ABS_PRESSURE, press);
> + input_report_key(st->input, BTN_TOUCH, 1);
> + input_sync(st->input);
> +
This would be back in the callback buffer code once the
callback has run.
Has the interesting side effect of making this code effectively generic.
It no longer has any ties to the at91 at all that I can spot.
Just a selection of channels and a request for a particular trigger -
both of which could come from device tree.
> + iio_trigger_notify_done(st->trig);
> + return;
> +
> +at91_rts_workq_handler_end_touch:
> + /* report end of touch */
> + input_report_key(st->input, BTN_TOUCH, 0);
> + input_sync(st->input);
> +at91_rts_workq_handler_exit:
> + iio_trigger_notify_done(st->trig);
> +}
> +
> +static int at91_rts_open(struct input_dev *dev)
> +{
> + int ret;
> + struct at91_rts *st = input_get_drvdata(dev);
> +
> + /* avoid multiple initialization in case touchscreen is opened again */
> + if (st->adc_connected)
> + return 0;
> +
> + /*
> + * First, look for the channels. It is possible that the ADC device
> + * did not probe yet, but we already probed, so we returning probe defer
> + * doesn't make much sense.
Quite - so why not do the obvious and request these in the probe and hold
them until remove? Then if they aren't ready defer the probe. This driver
is useless until the ADC is there so why let it successfully probe before
that point?
> + */
> + st->chan_x = iio_channel_get(dev->dev.parent, "x");
> + if (IS_ERR_OR_NULL(st->chan_x)) {
> + dev_err(dev->dev.parent, "cannot get X channel from ADC");
> + ret = PTR_ERR(st->chan_x);
> + goto at91_rts_open_free_chan;
> + }
> +
> + st->chan_y = iio_channel_get(dev->dev.parent, "y");
> + if (IS_ERR_OR_NULL(st->chan_y)) {
> + dev_err(dev->dev.parent, "cannot get Y channel from ADC");
> + ret = PTR_ERR(st->chan_y);
> + goto at91_rts_open_free_chan;
> + }
> +
> + st->chan_pressure = iio_channel_get(dev->dev.parent, "pressure");
> + if (IS_ERR_OR_NULL(st->chan_pressure)) {
> + dev_err(dev->dev.parent, "cannot get pressure channel from ADC");
> + ret = PTR_ERR(st->chan_pressure);
> + goto at91_rts_open_free_chan;
> + }
> +
> + /* look for the trigger in device tree */
> + st->trig = iio_trigger_find(dev->dev.parent, NULL);
> + if (IS_ERR_OR_NULL(st->trig)) {
> + dev_err(dev->dev.parent, "cannot get trigger from ADC");
> + ret = PTR_ERR(st->trig)
This also feels like it should be retrieved during the probe and we should
defer if that fails. Can't do anything useful without it!
> + goto at91_rts_open_free_chan;
> + }
> +
> + /* allocate a pollfunc for the trigger */
> + st->rts_pf = iio_alloc_pollfunc(at91_rts_trigger_handler, NULL,
> + IRQF_ONESHOT, NULL,
> + dev->dev.parent->of_node->name);
> + if (!st->rts_pf) {
> + ret = -ENOMEM;
> + dev_err(dev->dev.parent, "cannot allocate trigger pollfunc");
> + goto at91_rts_open_free_chan;
> + }
> +
> + iio_pollfunc_set_private_data(st->rts_pf, st);
> +
> + /*
> + * Attach the pollfunc to the trigger. This will also call the
> + * configure function to enable the trigger
> + */
> + ret = iio_trigger_attach_poll_func(st->trig, st->rts_pf);
> + if (ret)
> + goto at91_rts_open_dealloc_pf;
Ah. Now I think I see why you needed the poll function rather than
doing this with a callback buffer.
I'd rather see a consumer interface that requests the whole ADC runs on
a particular trigger.
> +
> + dev_dbg(dev->dev.parent, "channels found, attached to trigger");
> +
> + st->adc_connected = true;
> + return 0;
> +
> +at91_rts_open_dealloc_pf:
> + iio_dealloc_pollfunc(st->rts_pf);
> +at91_rts_open_free_chan:
> + if (!IS_ERR_OR_NULL(st->chan_x))
> + iio_channel_release(st->chan_x);
> + if (!IS_ERR_OR_NULL(st->chan_y))
> + iio_channel_release(st->chan_y);
> + if (!IS_ERR_OR_NULL(st->chan_pressure))
> + iio_channel_release(st->chan_pressure);
> + /*
> + * Avoid keeping old values in channel pointers. in case some channel
> + * failed and we reopen them, and now fail, we will have invalid values
> + * to release. So write them as NULL now.
> + */
> + st->chan_x = NULL;
> + st->chan_y = NULL;
> + st->chan_pressure = NULL;
> + return ret;
> +}
> +
> +static void at91_rts_close(struct input_dev *dev)
> +{
> + struct at91_rts *st = input_get_drvdata(dev);
> +
> + if (!st->adc_connected)
> + return;
> +
> + iio_trigger_detach_poll_func(st->trig, st->rts_pf);
> + iio_dealloc_pollfunc(st->rts_pf);
> +
> + if (!IS_ERR_OR_NULL(st->chan_x))
> + iio_channel_release(st->chan_x);
> + if (!IS_ERR_OR_NULL(st->chan_y))
> + iio_channel_release(st->chan_y);
> + if (!IS_ERR_OR_NULL(st->chan_pressure))
> + iio_channel_release(st->chan_pressure);
> +
> + st->adc_connected = false;
> +}
> +
> +static int at91_rts_probe(struct platform_device *pdev)
> +{
> + int ret;
> + struct at91_rts *st;
> + struct input_dev *input;
> + struct device *dev = &pdev->dev;
> + struct device_node *node = dev->of_node;
> +
> + st = devm_kzalloc(dev, sizeof(struct at91_rts), GFP_KERNEL);
> + if (!st)
> + return -ENOMEM;
> + st->adc_connected = false;
> +
> + INIT_WORK(&st->workq, at91_rts_workq_handler);
> +
> + input = devm_input_allocate_device(dev);
> + if (!input) {
> + dev_err(dev, "failed to allocate input device\n");
> + return -ENOMEM;
> + }
> +
> + ret = of_property_read_u32(node, "microchip,pressure-threshold",
> + &st->pressure_threshold);
> + if (ret < 0) {
> + dev_dbg(dev, "can't get touchscreen pressure threshold property.\n");
> + st->pressure_threshold = AT91_RTS_DEFAULT_PRESSURE_THRESHOLD;
> + }
> +
> + input->name = DRIVER_NAME;
> + input->id.bustype = BUS_HOST;
> + input->dev.parent = &pdev->dev;
> + input->open = at91_rts_open;
> + input->close = at91_rts_close;
> +
> + input_set_abs_params(input, ABS_X, 0, MAX_POS_MASK - 1, 0, 0);
> + input_set_abs_params(input, ABS_Y, 0, MAX_POS_MASK, 0, 0);
> + input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0);
> +
> + input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
> + input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
> +
> + st->input = input;
> + input_set_drvdata(input, st);
> +
> + ret = input_register_device(input);
> + if (ret) {
> + dev_err(dev, "failed to register input device: %d", ret);
> + return ret;
> + }
> +
> + platform_set_drvdata(pdev, st);
> +
> + dev_info(dev, "probed successfully\n");
Not useful. There are many ways to find this out without looking at dmesg.
Please remove.
> + return 0;
> +}
> +
> +static int at91_rts_remove(struct platform_device *pdev)
> +{
> + struct at91_rts *st = platform_get_drvdata(pdev);
> +
> + input_unregister_device(st->input);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id at91_rts_of_match[] = {
> + {
> + .compatible = "microchip,sama5d2-resistive-touch",
> + }, {
> + /* sentinel */
> + },
> +};
> +MODULE_DEVICE_TABLE(of, at91_rts_of_match);
> +
> +static struct platform_driver atmel_rts_driver = {
> + .probe = at91_rts_probe,
> + .remove = at91_rts_remove,
> + .driver = {
> + .name = DRIVER_NAME,
> + .of_match_table = of_match_ptr(at91_rts_of_match),
> + },
> +};
> +
> +module_platform_driver(atmel_rts_driver);
> +
> +MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com>");
> +MODULE_DESCRIPTION("Microchip SAMA5D2 Resistive Touch Driver");
> +MODULE_LICENSE("GPL v2");
^ permalink raw reply
* [PATCH 09/14] iio: inkern: triggers: create helpers for OF trigger retrieval
From: Jonathan Cameron @ 2017-12-29 17:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513955241-10985-10-git-send-email-eugen.hristev@microchip.com>
On Fri, 22 Dec 2017 17:07:16 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> Create helper API to get trigger information from OF regarding
> trigger producer/consumer for iio triggers.
> The functions will search for matching trigger by name, similar
> with channel retrieval
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
This makes sense once we make the touchscreen driver truely generic.
If it wasn't generic this could be rolled up as data within that driver.
A few small comments inline.
> ---
> drivers/iio/inkern.c | 91 ++++++++++++++++++++++++++++++++++++
> include/linux/iio/trigger_consumer.h | 1 +
> 2 files changed, 92 insertions(+)
>
> diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
> index 069defc..58bd18d 100644
> --- a/drivers/iio/inkern.c
> +++ b/drivers/iio/inkern.c
> @@ -14,9 +14,13 @@
>
> #include <linux/iio/iio.h>
> #include "iio_core.h"
> +#include "iio_core_trigger.h"
> #include <linux/iio/machine.h>
> #include <linux/iio/driver.h>
> #include <linux/iio/consumer.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +
Don't add white space here.
>
> struct iio_map_internal {
> struct iio_dev *indio_dev;
> @@ -262,6 +266,39 @@ static struct iio_channel *of_iio_channel_get_all(struct device *dev)
> return ERR_PTR(ret);
> }
>
> +#ifdef CONFIG_IIO_TRIGGER
Hmm. Generally frowned upon to have ifdef blocks inline within c files.
Perhaps worth pulling these out to inkern-trigger.c and using Kconfig magic
to build if relevant - not worth splitting the header though.
> +
> +static struct iio_trigger *of_iio_trigger_get(struct device_node *np, int index)
> +{
> + struct device *idev;
> + struct iio_dev *indio_dev;
> + int err;
> + struct of_phandle_args iiospec;
> + struct iio_trigger *trig;
> +
> + err = of_parse_phandle_with_args(np, "io-triggers",
> + "#io-trigger-cells",
> + index, &iiospec);
> + if (err)
> + return ERR_PTR(err);
> +
> + idev = bus_find_device(&iio_bus_type, NULL, iiospec.np,
> + iio_dev_node_match);
> + of_node_put(iiospec.np);
> + if (!idev)
> + return ERR_PTR(-EPROBE_DEFER);
> +
> + indio_dev = dev_to_iio_dev(idev);
> +
> + trig = iio_trigger_find_from_device(indio_dev, iiospec.args[0]);
> +
> + if (!trig)
> + return ERR_PTR(-ENODEV);
> +
> + return trig;
> +}
> +#endif /* CONFIG_IIO_TRIGGER */
> +
> #else /* CONFIG_OF */
>
> static inline struct iio_channel *
> @@ -275,6 +312,12 @@ static inline struct iio_channel *of_iio_channel_get_all(struct device *dev)
> return NULL;
> }
>
> +static inline struct iio_trigger *of_iio_trigger_get(struct device_node *np,
> + int index)
> +{
> + return NULL;
> +}
> +
> #endif /* CONFIG_OF */
>
> static struct iio_channel *iio_channel_get_sys(const char *name,
> @@ -927,3 +970,51 @@ ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
> chan->channel, buf, len);
> }
> EXPORT_SYMBOL_GPL(iio_write_channel_ext_info);
> +
> +#ifdef CONFIG_IIO_TRIGGER
> +struct iio_trigger *iio_trigger_find(struct device *dev, char *name)
> +{
> + struct device_node *np = dev->of_node;
> + struct iio_trigger *trig = NULL;
> +
> + /* Walk up the tree of devices looking for a matching iio trigger */
> + while (np) {
> + int index = 0;
> +
> + /*
> + * For named iio triggers, first look up the name in the
> + * "io-trigger-names" property. If it cannot be found, the
> + * index will be an error code, and of_iio_trigger_get()
> + * will fail.
> + */
> + if (name)
> + index = of_property_match_string(np, "io-trigger-names",
> + name);
> + trig = of_iio_trigger_get(np, index);
> + if (!IS_ERR(trig) || PTR_ERR(trig) == -EPROBE_DEFER) {
> + break;
> + } else if (name && index >= 0) {
> + pr_err("ERROR: could not get IIO trigger %pOF:%s(%i)\n",
> + np, name ? name : "", index);
> + return trig;
> + }
> +
> + /*
> + * No matching IIO trigger found on this node.
> + * If the parent node has a "io-trigger-ranges" property,
> + * then we can try one of its channels.
> + */
> + np = np->parent;
> + if (np && !of_get_property(np, "io-trigger-ranges", NULL))
> + return trig;
> + }
> +
> + if (!trig || (IS_ERR(trig) && PTR_ERR(trig) != -EPROBE_DEFER))
> + dev_dbg(dev, "error retrieving trigger information\n");
> + else
> + dev_dbg(dev, "trigger found: %s\n", name);
> +
> + return trig;
> +}
> +EXPORT_SYMBOL_GPL(iio_trigger_find);
> +#endif /* CONFIG_IIO_TRIGGER */
> diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h
> index 13be595..b2fc485 100644
> --- a/include/linux/iio/trigger_consumer.h
> +++ b/include/linux/iio/trigger_consumer.h
> @@ -62,6 +62,7 @@ irqreturn_t iio_pollfunc_store_time(int irq, void *p);
>
> void iio_trigger_notify_done(struct iio_trigger *trig);
>
> +struct iio_trigger *iio_trigger_find(struct device *dev, char *name);
> /*
> * Two functions for common case where all that happens is a pollfunc
> * is attached and detached from a trigger
^ permalink raw reply
* [PATCH 07/14] iio: triggers: on pollfunc attach, complete iio_dev if NULL
From: Jonathan Cameron @ 2017-12-29 17:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513955241-10985-8-git-send-email-eugen.hristev@microchip.com>
On Fri, 22 Dec 2017 17:07:14 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> When attaching a pollfunc to a trigger, if the pollfunc does not
> have an associated iio_dev pointer, just use the private data
> iio_dev pointer from the trigger to fill in the poll func required
> iio_dev reference.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
I'm yet to be convinced this is necessary rather than using a callback
buffer. It's also decidedly unsafe as there is no particular reason
in general to assume the private data is an iio_dev.
> ---
> drivers/iio/industrialio-trigger.c | 9 +++++++++
> include/linux/iio/trigger_consumer.h | 2 ++
> 2 files changed, 11 insertions(+)
>
> diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
> index 8565c92..ab180bd 100644
> --- a/drivers/iio/industrialio-trigger.c
> +++ b/drivers/iio/industrialio-trigger.c
> @@ -272,6 +272,15 @@ int iio_trigger_attach_poll_func(struct iio_trigger *trig,
> bool notinuse
> = bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
>
> + /*
> + * If we did not get a iio_dev in the poll func, attempt to
> + * obtain the trigger's owner's device struct
> + */
> + if (!pf->indio_dev)
> + pf->indio_dev = iio_trigger_get_drvdata(trig);
That isn't always valid. Triggers don't always have a iio_dev associated
with them at all.
> + if (!pf->indio_dev)
> + return -EINVAL;
> +
> /* Prevent the module from being removed whilst attached to a trigger */
> __module_get(pf->indio_dev->driver_module);
>
> diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h
> index aeefcdb..36e2a02 100644
> --- a/include/linux/iio/trigger_consumer.h
> +++ b/include/linux/iio/trigger_consumer.h
> @@ -63,6 +63,8 @@ int iio_triggered_buffer_predisable(struct iio_dev *indio_dev);
> /*
> * Two functions for the uncommon case when we need to attach or detach
> * a specific pollfunc to and from a trigger
> + * If the pollfunc has a NULL iio_dev pointer, it will be filled from the
> + * trigger struct.
> */
> int iio_trigger_attach_poll_func(struct iio_trigger *trig,
> struct iio_poll_func *pf);
^ permalink raw reply
* [PATCH 03/14] dt-bindings: iio: add binding support for iio trigger provider/consumer
From: Jonathan Cameron @ 2017-12-29 17:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171226223500.dxbp26bsx2ojbicr@rob-hp-laptop>
On Tue, 26 Dec 2017 16:35:00 -0600
Rob Herring <robh@kernel.org> wrote:
> On Fri, Dec 22, 2017 at 05:07:10PM +0200, Eugen Hristev wrote:
> > Add bindings for producer/consumer for iio triggers.
> >
> > Similar with iio channels, the iio triggers can be connected between drivers:
> > one driver will be a producer by registering iio triggers, and another driver
> > will connect as a consumer.
> >
> > Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
In cases where the connectivity is entirely known to the various drivers
(battery chargers integrated in SoCs that use ADC channels for example) we
have always kept the map in driver.
I'm not yet entirely clear if we can do this here. Might make sense if
we can...
> > ---
> > .../devicetree/bindings/iio/iio-bindings.txt | 52 +++++++++++++++++++++-
> > 1 file changed, 51 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/devicetree/bindings/iio/iio-bindings.txt b/Documentation/devicetree/bindings/iio/iio-bindings.txt
> > index 68d6f8c..d861f0df 100644
> > --- a/Documentation/devicetree/bindings/iio/iio-bindings.txt
> > +++ b/Documentation/devicetree/bindings/iio/iio-bindings.txt
> > @@ -11,6 +11,10 @@ value of a #io-channel-cells property in the IIO provider node.
> >
> > [1] http://marc.info/?l=linux-iio&m=135902119507483&w=2
> >
> > +Moreover, the provider can have a set of triggers that can be attached to
> > +from the consumer drivers.
> > +
> > +
> > ==IIO providers==
> >
> > Required properties:
> > @@ -18,6 +22,11 @@ Required properties:
> > with a single IIO output and 1 for nodes with multiple
> > IIO outputs.
> >
> > +Optional properties:
> > +#io-trigger-cells: Number of cells for the IIO trigger specifier. Typically 0
> > + for nodes with a single IIO trigger and 1 for nodes with
> > + multiple IIO triggers.
> > +
> > Example for a simple configuration with no trigger:
> >
> > adc: voltage-sensor at 35 {
> > @@ -26,7 +35,7 @@ Example for a simple configuration with no trigger:
> > #io-channel-cells = <1>;
> > };
> >
> > -Example for a configuration with trigger:
> > +Example for a configuration with channels provided by trigger:
> >
> > adc at 35 {
> > compatible = "some-vendor,some-adc";
> > @@ -42,6 +51,17 @@ Example for a configuration with trigger:
> > };
> > };
> >
> > +Example for a configuration for a trigger provider:
> > +
> > + adc: sensor-with-trigger at 35 {
> > + compatible = "some-vendor,some-adc";
> > + reg = <0x35>;
> > + #io-channel-cells = <1>;
> > + #io-trigger-cells = <1>;
> > + /* other properties */
> > + };
> > +
> > +
> > ==IIO consumers==
> >
> > Required properties:
> > @@ -61,16 +81,38 @@ io-channel-ranges:
> > IIO channels from this node. Useful for bus nodes to provide
> > and IIO channel to their children.
> >
> > +io-triggers: List of phandle and IIO specifier pairs, one pair
> > + for each trigger input to the device. Note: if the
> > + IIO trigger provider specifies '0' for #io-trigger-cells,
> > + then only the phandle portion of the pair will appear.
> > +
> > +io-trigger-names:
> > + List of IIO trigger input name strings sorted in the same
> > + order as the io-triggers property. Consumers drivers
> > + will use io-trigger-names to match IIO trigger input names
> > + with IIO specifiers.
> > +
> > +io-trigger-ranges:
> > + Empty property indicating that child nodes can inherit named
> > + IIO triggers from this node. Useful for bus nodes to provide
> > + IIO triggers to their children.
>
> I think it would be better to be explicit in the child nodes. What's the
> use you had in mind?
>
> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] video/fbdev/wm8505fb: Delete an error message for a failed memory allocation in wm8505fb_probe()
From: Bartlomiej Zolnierkiewicz @ 2017-12-29 17:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8f4f12ca-f2b3-6b3b-5f4c-5519f13c474f@users.sourceforge.net>
On Friday, November 24, 2017 08:30:04 PM SF Markus Elfring wrote:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Fri, 24 Nov 2017 20:22:10 +0100
>
> Omit an extra message for a memory allocation failure in this function.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
> ---
> drivers/video/fbdev/wm8505fb.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/video/fbdev/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c
> index 253ffe9baab2..8f0d5379861d 100644
> --- a/drivers/video/fbdev/wm8505fb.c
> +++ b/drivers/video/fbdev/wm8505fb.c
> @@ -276,10 +276,8 @@ static int wm8505fb_probe(struct platform_device *pdev)
>
> fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) +
> sizeof(u32) * 16, GFP_KERNEL);
> - if (!fbi) {
> - dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
> + if (!fbi)
> return -ENOMEM;
> - }
This removes the information about the device for which the allocation
fails (but as there can be only one wm8505fb device in the system this
change is okay).
Patch queued for 4.16, thanks.
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* [PATCH] video/fbdev/vt8500lcdfb: Delete an error message for a failed memory allocation in vt8500lcd_probe()
From: Bartlomiej Zolnierkiewicz @ 2017-12-29 17:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d229eccd-ab20-d594-caa1-55fb464357ac@users.sourceforge.net>
On Friday, November 24, 2017 08:53:02 PM SF Markus Elfring wrote:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Fri, 24 Nov 2017 20:42:08 +0100
>
> Omit an extra message for a memory allocation failure in this function.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
> ---
> drivers/video/fbdev/vt8500lcdfb.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c
> index 1a1176bf0906..5c5cd2923041 100644
> --- a/drivers/video/fbdev/vt8500lcdfb.c
> +++ b/drivers/video/fbdev/vt8500lcdfb.c
> @@ -289,10 +289,8 @@ static int vt8500lcd_probe(struct platform_device *pdev)
>
> fbi = devm_kzalloc(&pdev->dev, sizeof(struct vt8500lcd_info)
> + sizeof(u32) * 16, GFP_KERNEL);
> - if (!fbi) {
> - dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
> + if (!fbi)
> return -ENOMEM;
> - }
>
This removes the information about the device for which the allocation
fails (but as there can be only one vt8500lcdfb device in the system this
change is okay).
Patch queued for 4.16, thanks.
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* [RFC PATCH v12 5/5] arm64: dts: rockchip: Move PCIe WAKE# irq to pcie port for Gru
From: Tony Lindgren @ 2017-12-29 17:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171226023646.17722-6-jeffy.chen@rock-chips.com>
* Jeffy Chen <jeffy.chen@rock-chips.com> [171226 02:41]:
> Currently we are handling PCIe WAKE# irq in mrvl wifi driver.
>
> Move it to rockchip pcie port since we are going to handle it in the
> pci core.
Yes in the PCIe case, the pcie port node is the right place for
the wakeirq instead of the child the mvl_wifi node. So one
question further down below to verify this..
> Also avoid this irq been considered as the PCI interrupt pin in the
> of_irq_parse_pci().
The above paragraph needs a bit more clarification to be
readable :)
> --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
> @@ -719,15 +719,16 @@ ap_i2c_audio: &i2c8 {
> #size-cells = <2>;
> ranges;
>
> + interrupts-extended = <&pcie0 1>, <&gpio0 8 IRQ_TYPE_LEVEL_LOW>;
> + interrupt-names = "pci", "wakeup";
> + pinctrl-names = "default";
> + pinctrl-0 = <&wlan_host_wake_l>;
> + wakeup-source;
> +
> mvl_wifi: wifi at 0,0 {
> compatible = "pci1b4b,2b42";
> reg = <0x83010000 0x0 0x00000000 0x0 0x00100000
> 0x83010000 0x0 0x00100000 0x0 0x00100000>;
> - interrupt-parent = <&gpio0>;
> - interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
> - pinctrl-names = "default";
> - pinctrl-0 = <&wlan_host_wake_l>;
> - wakeup-source;
> };
> };
> };
So the above modifies pcie at 0,0 node. And that node describes
the particular PCIe port that the WLAN is connected to instead
of describing the whole PCIe controller device, right?
If so, then yeah it's totally where the wakeirq should be
defined for a PCIe device in the dts file :)
Regards,
Tony
^ permalink raw reply
* [PATCH net-next 5/6] arm64: dts: marvell: mcbin: enable the fourth network interface
From: Antoine Tenart @ 2017-12-29 21:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171228185920.GW10595@n2100.armlinux.org.uk>
Hi Russell,
On Thu, Dec 28, 2017 at 06:59:21PM +0000, Russell King - ARM Linux wrote:
> On Thu, Dec 28, 2017 at 11:04:16AM +0100, Antoine Tenart wrote:
> >
> > That's not what I remembered. You had some valid points, and others
> > related to PHY modes the driver wasn't supporting before the phylink
> > transition. My understanding of this was that you wanted a full
> > featured support while I only wanted to convert the already supported
> > modes.
>
> You are mistaken - you can get a full refresher on where things were
> at via https://patchwork.kernel.org/patch/9963971/
I read it again and still have the same feeling. There's been a
misunderstanding at some point. Anyway, let's move forward :)
> 1. I asked for details about what mvpp2.c supports that phylink does
> not (as you indicated that there were certain things that mvpp2
> supports that phylink does not.) I'm still awaiting a response.
I don't remember PHY modes supported in the PPv2 driver that aren't
supported in PHYLINK. I think this point is the main misunderstanding. I
thought you wanted me to support modes unsupported in the PPv2 driver
before. But you explained quite well what these comments were about
below.
So I guess this point is resolved (aka I'll have to take your comments
into account for the v2).
> 2. 25th Sept, you indicated that you would get someone to test
> an issue related to in-band AN. No results of that testing have
> been forthcoming.
That's right. I asked someone to make a test, but did not get an answer.
And because the PHYLINK patch stalled on my side I kinda forget about
it. I'll try again to have this test made.
> I am not after a full featured support, what I'm after is ensuring
> that phylink is (a) used correctly and (b) implementations using it
> are correct. Part of that is ensuring that users don't introduce
> unexpected failure conditions.
>
> So, when you do this in the validate() callback:
>
> + phylink_set(mask, 1000baseX_Full);
>
> and then do this in the mac_config() callback:
>
> + if (!phy_interface_mode_is_rgmii(port->phy_interface) &&
> + port->phy_interface != PHY_INTERFACE_MODE_SGMII)
> + return;
>
> and this in the link_state() callback:
>
> + if (!phy_interface_mode_is_rgmii(port->phy_interface) &&
> + port->phy_interface != PHY_INTERFACE_MODE_SGMII)
> + return 0;
>
> the result is that phylink thinks that you support 1000base-X modes,
> and it will call mac_config() asking for 1000base-X, but you silently
> ignore that, leaving the hardware configured in whatever state it was.
> That leads to a silent failure as far as the user is concerned.
>
> So, if you do not intend to support 1000base-X initially, don't
> allow it in the validate callback until you do.
>
> It gets worse, because the return in link_state() means that phylink
> thinks that the link is up if it has requested 1000base-X, which it
> won't be unless you've properly configured it.
>
> It's this kind of unreliability that I was concerned about in your
> patch. I'm not demanding "full featured implementation" but I do
> want you to use it correctly.
Thanks for the detailed explanations!
> > > What I'm most concerned about, given the bindings for comphy that
> > > have been merged, is that Free Electrons is pushing forward seemingly
> > > with no regard to the requirement that the serdes lanes are dynamically
> > > reconfigurable, and that's a basic requirement for SFP, and for the
> > > 88x3310 PHYs on the Macchiatobin platform.
> >
> > The main idea behind the comphy driver is to provide a way to
> > reconfigure the serdes lanes at runtime. Could you develop what are
> > blocking points to properly support SFP, regarding the current comphy
> > support?
>
> If it supports serdes lane mode reconfiguration (iow, switching between
> 1000base-X, 2500base-X, SGMII, 10G-KR), then that's all that's required.
It does, and the PPv2 driver already ask the COMPHY driver to perform
these reconfigurations (when using the 10G/1G interface on the mcbin for
example).
Thanks!
Antoine
--
Antoine T?nart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH v6 4/5] clk: aspeed: Register gated clocks
From: Benjamin Herrenschmidt @ 2017-12-29 22:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171227013227.GV7997@codeaurora.org>
On Tue, 2017-12-26 at 17:32 -0800, Stephen Boyd wrote:
> > I noticed we do have a few i2c based clock drivers... how are they ever
> > supposed to work ? i2c bus controllers are allowed to sleep and the i2c
> > core takes mutexes...
>
> We have clk_prepare()/clk_unprepare() for sleeping suckage. You
> can use that, and i2c based clk drivers do that today.
"suckage" ? Hehe ... the suckage should rather be stuff that cannot
sleep. Arbitrary latencies and jitter caused by too much code wanting
to be "atomic" when unnecessary are a bad thing.
In the case of clocks like the aspeed where we have to wait for a
rather long stabilization delay, way too long to legitimately do a non-
sleepable delay with a lock held, do we need to do everything in
prepare() then ?
Ben.
^ 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