Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 6/8] phy: st-miphy-40lp: Add SPEAr1310 and SPEAr1340 PCIe phy support
From: Arnd Bergmann @ 2014-02-06 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <dca9c501de8386003142b463469c3d267a049eeb.1391661589.git.pratyush.anand@st.com>

On Thursday 06 February 2014, Pratyush Anand wrote:
> +static int spear1310_pcie_miphy_exit(struct st_miphy40lp_priv *phypriv)
> +{
> +       u32 mask;
> +
> +       switch (phypriv->id) {
> +       case 0:
> +               mask = SPEAR1310_PCIE_CFG_MASK(0);
> +               break;
> +       case 1:
> +               mask = SPEAR1310_PCIE_CFG_MASK(1);
> +               break;
> +       case 2:
> +               mask = SPEAR1310_PCIE_CFG_MASK(2);
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       regmap_update_bits(phypriv->misc, SPEAR1310_PCIE_SATA_CFG,
> +                       SPEAR1310_PCIE_CFG_MASK(phypriv->id), 0);
> +
> +       regmap_update_bits(phypriv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
> +                       SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK, 0);
> +
> +       return 0;
> +}

hmm, you set the mask based on the id, but then use the macro below
and ignore the mask?

> +
> +static int pcie_miphy_init(struct st_miphy40lp_priv *phypriv)
> +{
> +       if (of_device_is_compatible(phypriv->np, "st,spear1340-miphy"))
> +               return spear1340_pcie_miphy_init(phypriv);
> +       else if (of_device_is_compatible(phypriv->np, "st,spear1310-miphy"))
> +               return spear1310_pcie_miphy_init(phypriv);
> +       else
> +               return -EINVAL;
> +}
> +
> +static int pcie_miphy_exit(struct st_miphy40lp_priv *phypriv)
> +{
> +       if (of_device_is_compatible(phypriv->np, "st,spear1340-miphy"))
> +               return spear1340_pcie_miphy_exit(phypriv);
> +       else if (of_device_is_compatible(phypriv->np, "st,spear1310-miphy"))
> +               return spear1310_pcie_miphy_exit(phypriv);
> +       else
> +               return -EINVAL;
> +}

I think it's better to make this code table-driven. Rather than checking
'of_device_is_compatible()', it's much easier to add a .data field to
the of_device_id array that describes the PHY. You can use .data to
point to a structure containing per-device function pointers or
(better) values and offsets to be used.

	Arnd

^ permalink raw reply

* [RFC/RFT 1/2] ARM: mm: introduce arch hooks for dma address translation routines
From: Dave Martin @ 2014-02-06 15:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F284F3.3080601@ti.com>

On Wed, Feb 05, 2014 at 06:37:39PM +0000, Santosh Shilimkar wrote:
> Dave,
> 
> On Wednesday 05 February 2014 11:23 AM, Dave Martin wrote:

[...]

> > Santosh, bearing these arguments in mind, do you think that dma-ranges
> > is natural for your hardware?
> > 
> > The answer may be "yes", but if we're having to twist things to fit,
> > by having to describe something fake or unreal in DT and/or writing board
> > specific code to work around it, that motivates coming up with a better
> > way of describing the hardware in these cases.
> >
> The answer at least not fully "yes" with the limited look at dma-ranges
> so far.
> - The of_translate_dma_address() can be used to translate addresses
> from DMA to CPU address space. And this should work but it will be
> expensive compared to classic macro's.
> - We don't see a way for CPU -> DMA addresses translation using DT.
> Probably some more digging/pointers are is needed.

Are you saying that dma-ranges does correctly describe your hardware,
but the kernel frameworks are inadequate or suboptimal for making use of
this information?

This is a different problem from not being able to describe the hardware.

Cheers
---Dave

^ permalink raw reply

* [PATCH 4/4] ARM: Kirkwood: Add support for many Synology NAS devices
From: Jason Cooper @ 2014-02-06 15:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391634309-3123-5-git-send-email-andrew@lunn.ch>


+ devicetree ML, DT maintainers

On Wed, Feb 05, 2014 at 10:05:09PM +0100, Andrew Lunn wrote:
> Add device tree fragments and files to support many of the kirkwood
> based Synology NAS devices. This is a translation of the board setup
> file maintained by Ben Peddell <klightspeed@killerwolves.net>
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> Tested by Ben Peddell <klightspeed@killerwolves.net>
> cc: Ben Peddell <klightspeed@killerwolves.net>
> ---
> 
> v2:
> Fix gpio's which should be gpo.
> Rebase onto v3-14-rc1
> Update RTC nodes with vendor name.
> Update SPI flash node with vendor name.
> ---
>  arch/arm/boot/dts/Makefile                     |   15 ++++
>  arch/arm/boot/dts/kirkwood-ds109.dts           |   33 +++++++
>  arch/arm/boot/dts/kirkwood-ds110jv10.dts       |   33 +++++++
>  arch/arm/boot/dts/kirkwood-ds111.dts           |   33 +++++++
>  arch/arm/boot/dts/kirkwood-ds112.dts           |   34 +++++++
>  arch/arm/boot/dts/kirkwood-ds209.dts           |   33 +++++++
>  arch/arm/boot/dts/kirkwood-ds210.dts           |   35 ++++++++
>  arch/arm/boot/dts/kirkwood-ds212.dts           |   37 ++++++++
>  arch/arm/boot/dts/kirkwood-ds212j.dts          |   34 +++++++
>  arch/arm/boot/dts/kirkwood-ds409.dts           |   34 +++++++
>  arch/arm/boot/dts/kirkwood-ds409slim.dts       |   32 +++++++
>  arch/arm/boot/dts/kirkwood-ds411.dts           |   35 ++++++++
>  arch/arm/boot/dts/kirkwood-ds411j.dts          |   34 +++++++
>  arch/arm/boot/dts/kirkwood-ds411slim.dts       |   34 +++++++
>  arch/arm/boot/dts/kirkwood-rs212.dts           |   34 +++++++
>  arch/arm/boot/dts/kirkwood-rs409.dts           |   33 +++++++
>  arch/arm/boot/dts/kirkwood-rs411.dts           |   34 +++++++
>  arch/arm/boot/dts/synology/alarm-led-12.dtsi   |   28 ++++++
>  arch/arm/boot/dts/synology/common.dtsi         |  112 ++++++++++++++++++++++++
>  arch/arm/boot/dts/synology/ethernet-1.dtsi     |   15 ++++
>  arch/arm/boot/dts/synology/fan-alarm-18.dtsi   |   22 +++++
>  arch/arm/boot/dts/synology/fan-alarm-35-1.dtsi |   22 +++++
>  arch/arm/boot/dts/synology/fan-alarm-35-3.dtsi |   32 +++++++
>  arch/arm/boot/dts/synology/fan-gpios-15.dtsi   |   34 +++++++
>  arch/arm/boot/dts/synology/fan-gpios-32.dtsi   |   34 +++++++
>  arch/arm/boot/dts/synology/fan-speed-100.dtsi  |   20 +++++
>  arch/arm/boot/dts/synology/fan-speed-120.dtsi  |   20 +++++
>  arch/arm/boot/dts/synology/fan-speed-150.dtsi  |   20 +++++
>  arch/arm/boot/dts/synology/hdd-leds-20.dtsi    |   90 +++++++++++++++++++
>  arch/arm/boot/dts/synology/hdd-leds-21-1.dtsi  |   36 ++++++++
>  arch/arm/boot/dts/synology/hdd-leds-21-2.dtsi  |   52 +++++++++++
>  arch/arm/boot/dts/synology/hdd-leds-36.dtsi    |  103 ++++++++++++++++++++++
>  arch/arm/boot/dts/synology/hdd-leds-38.dtsi    |   52 +++++++++++
>  arch/arm/boot/dts/synology/hdd-power-29.dtsi   |   56 ++++++++++++
>  arch/arm/boot/dts/synology/hdd-power-30-1.dtsi |   40 +++++++++
>  arch/arm/boot/dts/synology/hdd-power-30-2.dtsi |   56 ++++++++++++
>  arch/arm/boot/dts/synology/hdd-power-30-4.dtsi |   89 +++++++++++++++++++
>  arch/arm/boot/dts/synology/hdd-power-31.dtsi   |   40 +++++++++
>  arch/arm/boot/dts/synology/hdd-power-34.dtsi   |   73 +++++++++++++++
>  arch/arm/boot/dts/synology/i2c-rtc-ricoh.dtsi  |   18 ++++
>  arch/arm/boot/dts/synology/i2c-rtc-seiko.dtsi  |   18 ++++
>  arch/arm/boot/dts/synology/pcie-2.dtsi         |   19 ++++
>  42 files changed, 1658 insertions(+)
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds109.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds110jv10.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds111.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds112.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds209.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds210.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds212.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds212j.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds409.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds409slim.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds411.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds411j.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-ds411slim.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-rs212.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-rs409.dts
>  create mode 100644 arch/arm/boot/dts/kirkwood-rs411.dts
>  create mode 100644 arch/arm/boot/dts/synology/alarm-led-12.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/common.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/ethernet-1.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-alarm-18.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-alarm-35-1.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-alarm-35-3.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-gpios-15.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-gpios-32.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-speed-100.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-speed-120.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/fan-speed-150.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-20.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-21-1.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-21-2.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-36.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-38.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-power-29.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-power-30-1.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-power-30-2.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-power-30-4.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-power-31.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/hdd-power-34.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/i2c-rtc-ricoh.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/i2c-rtc-seiko.dtsi
>  create mode 100644 arch/arm/boot/dts/synology/pcie-2.dtsi

Holy sh*t!  I know we're adding 15 boards, but this is, imho,
over-fragmenting.  I'm sure there's a reason you chose this path, but
you haven't explained why in your commit log. So I'm left guessing...

thx,

Jason.

> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index b9d6a8b485e0..6cf3a54ef7f1 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -89,6 +89,18 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
>  	kirkwood-dns325.dtb \
>  	kirkwood-dockstar.dtb \
>  	kirkwood-dreamplug.dtb \
> +	kirkwood-ds109.dtb \
> +	kirkwood-ds110jv10.dtb \
> +	kirkwood-ds111.dtb \
> +	kirkwood-ds209.dtb \
> +	kirkwood-ds210.dtb \
> +	kirkwood-ds212.dtb \
> +	kirkwood-ds212j.dtb \
> +	kirkwood-ds409.dtb \
> +	kirkwood-ds409slim.dtb \
> +	kirkwood-ds411.dtb \
> +	kirkwood-ds411j.dtb \
> +	kirkwood-ds411slim.dtb \
>  	kirkwood-goflexnet.dtb \
>  	kirkwood-guruplug-server-plus.dtb \
>  	kirkwood-ib62x0.dtb \
> @@ -111,6 +123,9 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
>  	kirkwood-nsa310a.dtb \
>  	kirkwood-openblocks_a6.dtb \
>  	kirkwood-openblocks_a7.dtb \
> +	kirkwood-rs212.dtb \
> +	kirkwood-rs409.dtb \
> +	kirkwood-rs411.dtb \
>  	kirkwood-sheevaplug.dtb \
>  	kirkwood-sheevaplug-esata.dtb \
>  	kirkwood-topkick.dtb \
> diff --git a/arch/arm/boot/dts/kirkwood-ds109.dts b/arch/arm/boot/dts/kirkwood-ds109.dts
> new file mode 100644
> index 000000000000..bea085ad540a
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds109.dts
> @@ -0,0 +1,33 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-ricoh.dtsi"
> +#include "synology/fan-speed-150.dtsi"
> +#include "synology/fan-gpios-32.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-21-1.dtsi"
> +
> +/ {
> +	model = "Synology DS109, DS110, DS110jv20";
> +	compatible = "synology,ds109", "synology,ds110jv20",
> +		     "synology,ds110", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds110jv10.dts b/arch/arm/boot/dts/kirkwood-ds110jv10.dts
> new file mode 100644
> index 000000000000..d6b746952947
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds110jv10.dts
> @@ -0,0 +1,33 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/fan-speed-150.dtsi"
> +#include "synology/fan-gpios-32.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-21-1.dtsi"
> +
> +/ {
> +	model = "Synology DS110j v10 and v30";
> +	compatible = "synology,ds110jv10", "synology,ds110jv30",
> +		     "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds111.dts b/arch/arm/boot/dts/kirkwood-ds111.dts
> new file mode 100644
> index 000000000000..5f51e088903f
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds111.dts
> @@ -0,0 +1,33 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6282.dtsi"
> +#include "synology/pcie-2.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-21-1.dtsi"
> +
> +/ {
> +	model = "Synology DS111";
> +	compatible = "synology,ds111", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds112.dts b/arch/arm/boot/dts/kirkwood-ds112.dts
> new file mode 100644
> index 000000000000..cda3203a0824
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds112.dts
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6282.dtsi"
> +#include "synology/pcie-2.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-35.dtsi"
> +#include "synology/hdd-leds-21-2.dtsi"
> +#include "synology/hdd-power-30.dtsi"
> +
> +/ {
> +	model = "Synology DS111";
> +	compatible = "synology,ds111", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds209.dts b/arch/arm/boot/dts/kirkwood-ds209.dts
> new file mode 100644
> index 000000000000..b2ebb423e129
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds209.dts
> @@ -0,0 +1,33 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-ricoh.dtsi"
> +#include "synology/fan-speed-150.dtsi"
> +#include "synology/fan-gpios-32.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-21-2.dtsi"
> +#include "synology/hdd-power-31.dtsi"
> +
> +/ {
> +	model = "Synology DS209";
> +	compatible = "synology,ds209", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds210.dts b/arch/arm/boot/dts/kirkwood-ds210.dts
> new file mode 100644
> index 000000000000..8623dd63f44d
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds210.dts
> @@ -0,0 +1,35 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/fan-speed-150.dtsi"
> +#include "synology/fan-gpios-32.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-21-2.dtsi"
> +#include "synology/hdd-power-31.dtsi"
> +
> +/ {
> +	model = "Synology DS210 v10, v20, v30, DS211j";
> +	compatible = "synology,ds210jv10", "synology,ds210jv20",
> +		     "synology,ds210jv30", "synology,ds211j",
> +		     "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds212.dts b/arch/arm/boot/dts/kirkwood-ds212.dts
> new file mode 100644
> index 000000000000..89e091ce2174
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds212.dts
> @@ -0,0 +1,37 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6282.dtsi"
> +#include "synology/pcie-2.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-21-2.dtsi"
> +#include "synology/hdd-power-30-2.dtsi"
> +
> +/ {
> +	model = "Synology DS212, DS212p v10, v20, DS213air v10, DS213 v10";
> +	compatible = "synology,ds212", "synology,ds212pv10",
> +		     "synology,ds212pv10", "synology,ds212pv20",
> +		     "synology,ds213airv10", "synology,ds213v10",
> +		     "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds212j.dts b/arch/arm/boot/dts/kirkwood-ds212j.dts
> new file mode 100644
> index 000000000000..ed14b7bb695e
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds212j.dts
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-32.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-21-2.dtsi"
> +#include "synology/hdd-power-29.dtsi"
> +
> +/ {
> +	model = "Synology DS212j v10, v20";
> +	compatible = "synology,ds212jv10", "synology,ds212jv20",
> +		     "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds409.dts b/arch/arm/boot/dts/kirkwood-ds409.dts
> new file mode 100644
> index 000000000000..7000de1add08
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds409.dts
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-ricoh.dtsi"
> +#include "synology/ethernet-1.dtsi"
> +#include "synology/fan-speed-120.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-18.dtsi"
> +#include "synology/hdd-leds-36.dtsi"
> +#include "synology/alarm-led-12.dtsi"
> +
> +/ {
> +	model = "Synology DS409, DS410j";
> +	compatible = "synology,ds409", "synology,ds410j", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds409slim.dts b/arch/arm/boot/dts/kirkwood-ds409slim.dts
> new file mode 100644
> index 000000000000..0ba525a594f7
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds409slim.dts
> @@ -0,0 +1,32 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-ricoh.dtsi"
> +#include "synology/fan-speed-120.dtsi"
> +#include "synology/fan-gpios-32.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-20.dtsi"
> +
> +/ {
> +	model = "Synology 409slim";
> +	compatible = "synology,ds409slim", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds411.dts b/arch/arm/boot/dts/kirkwood-ds411.dts
> new file mode 100644
> index 000000000000..4c1ca8e85559
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds411.dts
> @@ -0,0 +1,35 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6282.dtsi"
> +#include "synology/pcie-2.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/ethernet-1.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-36.dtsi"
> +#include "synology/hdd-power-34.dtsi"
> +
> +/ {
> +	model = "Synology DS411, DS413jv10";
> +	compatible = "synology,ds411", "synology,ds413jv10", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds411j.dts b/arch/arm/boot/dts/kirkwood-ds411j.dts
> new file mode 100644
> index 000000000000..7f08a46ddabb
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds411j.dts
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/ethernet-1.dtsi"
> +#include "synology/fan-speed-120.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-18.dtsi"
> +#include "synology/hdd-leds-36.dtsi"
> +#include "synology/alarm-led-12.dtsi"
> +
> +/ {
> +	model = "Synology DS411j";
> +	compatible = "synology,ds411j", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-ds411slim.dts b/arch/arm/boot/dts/kirkwood-ds411slim.dts
> new file mode 100644
> index 000000000000..2e6d66f37002
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-ds411slim.dts
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6282.dtsi"
> +#include "synology/pcie-2.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/ethernet-1.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-35-1.dtsi"
> +#include "synology/hdd-leds-36.dtsi"
> +
> +/ {
> +	model = "Synology DS411slim";
> +	compatible = "synology,ds411slim", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-rs212.dts b/arch/arm/boot/dts/kirkwood-rs212.dts
> new file mode 100644
> index 000000000000..edc797464983
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-rs212.dts
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6282.dtsi"
> +#include "synology/pcie-2.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-35-3.dtsi"
> +#include "synology/hdd-leds-38.dtsi"
> +#include "synology/hdd-power-30-2.dtsi"
> +
> +/ {
> +	model = "Synology RS212";
> +	compatible = "synology,rs212", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-rs409.dts b/arch/arm/boot/dts/kirkwood-rs409.dts
> new file mode 100644
> index 000000000000..906664a99602
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-rs409.dts
> @@ -0,0 +1,33 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6281.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-ricoh.dtsi"
> +#include "synology/ethernet-1.dtsi"
> +#include "synology/fan-speed-120.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-18.dtsi"
> +#include "synology/hdd-leds-36.dtsi"
> +
> +/ {
> +	model = "Synology RS409";
> +	compatible = "synology,rs409", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/kirkwood-rs411.dts b/arch/arm/boot/dts/kirkwood-rs411.dts
> new file mode 100644
> index 000000000000..75c806ea0dc9
> --- /dev/null
> +++ b/arch/arm/boot/dts/kirkwood-rs411.dts
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "kirkwood.dtsi"
> +#include "kirkwood-6282.dtsi"
> +#include "synology/pcie-2.dtsi"
> +#include "synology/common.dtsi"
> +#include "synology/i2c-rtc-seiko.dtsi"
> +#include "synology/ethernet-1.dtsi"
> +#include "synology/fan-speed-100.dtsi"
> +#include "synology/fan-gpios-15.dtsi"
> +#include "synology/fan-alarm-35-3.dtsi"
> +#include "synology/hdd-leds-36.dtsi"
> +
> +/ {
> +	model = "Synology RS411 RS812";
> +	compatible = "synology,rs411", "synology,rs812", "marvell,kirkwood";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x8000000>;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200n8";
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/alarm-led-12.dtsi b/arch/arm/boot/dts/synology/alarm-led-12.dtsi
> new file mode 100644
> index 000000000000..e6ea8f07d1a5
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/alarm-led-12.dtsi
> @@ -0,0 +1,28 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_led_12: pmx-led-12 {
> +				marvell,pins = "mpp12";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +		pinctrl-0 = <&pmx_led_12>;
> +		pinctrl-names = "default";
> +		hdd1-green {
> +			label = "synology:alarm";
> +			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/common.dtsi b/arch/arm/boot/dts/synology/common.dtsi
> new file mode 100644
> index 000000000000..fb078c4f9a62
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/common.dtsi
> @@ -0,0 +1,112 @@
> +/*
> + * Nodes which are common to all Synology devices
> + *
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +
> +/ {
> +	mbus {
> +		pcie-controller {
> +			status = "okay";
> +
> +			pcie at 1,0 {
> +				status = "okay";
> +			};
> +		};
> +	};
> +	ocp at f1000000 {
> +		i2c at 11000 {
> +			status = "okay";
> +			clock-frequency = <400000>;
> +			pinctrl-0 = <&pmx_twsi0>;
> +			pinctrl-names = "default";
> +		};
> +		serial at 12000 {
> +			status = "okay";
> +			pinctrl-0 = <&pmx_uart0>;
> +			pinctrl-names = "default";
> +		};
> +		serial at 12100 {
> +			status = "okay";
> +			pinctrl-0 = <&pmx_uart1>;
> +			pinctrl-names = "default";
> +		};
> +		poweroff at 12100 {
> +			compatible = "synology,power-off";
> +			reg = <0x12000 0x100>;
> +			clocks = <&gate_clk 7>;
> +		};
> +		spi at 10600 {
> +			status = "okay";
> +			pinctrl-0 = <&pmx_spi>;
> +			pinctrl-names = "default";
> +
> +			m25p80 at 0 {
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				compatible = "st,m25p80";
> +				reg = <0>;
> +				spi-max-frequency = <20000000>;
> +				mode = <0>;
> +
> +				partition at 00000000 {
> +					reg = <0x00000000 0x00080000>;
> +					label = "RedBoot";
> +				};
> +
> +				partition at 00080000 {
> +					reg = <0x00080000 0x00200000>;
> +					label = "zImage";
> +				};
> +
> +				partition at 00280000 {
> +					reg = <0x00280000 0x00140000>;
> +					label = "rd.gz";
> +				};
> +				partition at 003c0000 {
> +					reg = <0x003c0000 0x00010000>;
> +					label = "vendor";
> +				};
> +				partition at 003d0000 {
> +					reg = <0x003d0000 0x00020000>;
> +					label = "RedBoot config";
> +				};
> +				partition at 003f0000 {
> +					reg = <0x003f0000 0x00010000>;
> +					label = "FIS directory";
> +				};
> +			};
> +		};
> +		sata at 80000 {
> +			pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
> +			pinctrl-names = "default";
> +			status = "okay";
> +			nr-ports = <2>;
> +		};
> +	};
> +	gpio_fan {
> +		compatible = "gpio-fan";
> +	};
> +};
> +
> +&mdio {
> +	status = "okay";
> +
> +	ethphy0: ethernet-phy {
> +		device_type = "ethernet-phy";
> +		reg = <8>;
> +	};
> +};
> +
> +&eth0 {
> +	status = "okay";
> +	ethernet0-port at 0 {
> +		phy-handle = <&ethphy0>;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/synology/ethernet-1.dtsi b/arch/arm/boot/dts/synology/ethernet-1.dtsi
> new file mode 100644
> index 000000000000..bf00eff53bbc
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/ethernet-1.dtsi
> @@ -0,0 +1,15 @@
> +&mdio {
> +	status = "okay";
> +
> +	ethphy1: ethernet-phy {
> +		device_type = "ethernet-phy";
> +		reg = <9>;
> +	};
> +};
> +
> +&eth0 {
> +	status = "okay";
> +	ethernet1-port at 0 {
> +		phy-handle = <&ethphy1>;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/synology/fan-alarm-18.dtsi b/arch/arm/boot/dts/synology/fan-alarm-18.dtsi
> new file mode 100644
> index 000000000000..d323eb0d2109
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-alarm-18.dtsi
> @@ -0,0 +1,22 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_fan_18: pmx-fan-18 {
> +				marvell,pins = "mpp18";
> +				marvell,function = "gpo";
> +			};
> +		};
> +	};
> +	gpio_fan {
> +		alarm-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/synology/fan-alarm-35-1.dtsi b/arch/arm/boot/dts/synology/fan-alarm-35-1.dtsi
> new file mode 100644
> index 000000000000..12e52fdae870
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-alarm-35-1.dtsi
> @@ -0,0 +1,22 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_fan_35: pmx-fan-35 {
> +				marvell,pins = "mpp35";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio_fan {
> +		alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/synology/fan-alarm-35-3.dtsi b/arch/arm/boot/dts/synology/fan-alarm-35-3.dtsi
> new file mode 100644
> index 000000000000..e2a44f402bf0
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-alarm-35-3.dtsi
> @@ -0,0 +1,32 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_fan_35: pmx-fan-35 {
> +				marvell,pins = "mpp35";
> +				marvell,function = "gpio";
> +			};
> +			pmx_fan_44: pmx-fan-44 {
> +				marvell,pins = "mpp44";
> +				marvell,function = "gpio";
> +			};
> +			pmx_fan_45: pmx-fan-45 {
> +				marvell,pins = "mpp45";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio_fan {
> +		alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH
> +			       &gpio1 12 GPIO_ACTIVE_HIGH
> +			       &gpio1 13 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/synology/fan-gpios-15.dtsi b/arch/arm/boot/dts/synology/fan-gpios-15.dtsi
> new file mode 100644
> index 000000000000..e27cba942eed
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-gpios-15.dtsi
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_fan_15: pmx-fan-15 {
> +				marvell,pins = "mpp15";
> +				marvell,function = "gpio";
> +			};
> +			pmx_fan_16: pmx-fan-16 {
> +				marvell,pins = "mpp16";
> +				marvell,function = "gpio";
> +			};
> +			pmx_fan_17: pmx-fan-17 {
> +				marvell,pins = "mpp17";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio_fan {
> +		pinctrl-0 = <&pmx_fan_15 &pmx_fan_16 &pmx_fan_17>;
> +		pinctrl-names = "default";
> +		gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
> +			 &gpio0 16 GPIO_ACTIVE_HIGH
> +			 &gpio0 17 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/synology/fan-gpios-32.dtsi b/arch/arm/boot/dts/synology/fan-gpios-32.dtsi
> new file mode 100644
> index 000000000000..d4fd393e71a8
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-gpios-32.dtsi
> @@ -0,0 +1,34 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_fan_32: pmx-fan-32 {
> +				marvell,pins = "mpp32";
> +				marvell,function = "gpio";
> +			};
> +			pmx_fan_33: pmx-fan-33 {
> +				marvell,pins = "mpp33";
> +				marvell,function = "gpo";
> +			};
> +			pmx_fan_34: pmx-fan-34 {
> +				marvell,pins = "mpp34";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio_fan {
> +		pinctrl-0 = <&pmx_fan_32 &pmx_fan_33 &pmx_fan_34>;
> +		pinctrl-names = "default";
> +		gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
> +			 &gpio1 1 GPIO_ACTIVE_HIGH
> +			 &gpio1 2 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/synology/fan-speed-100.dtsi b/arch/arm/boot/dts/synology/fan-speed-100.dtsi
> new file mode 100644
> index 000000000000..5188ba59a9b2
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-speed-100.dtsi
> @@ -0,0 +1,20 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	gpio_fan {
> +		gpio-fan,speed-map = <    0 0
> +				       2500 1
> +				       3100 2
> +				       3800 3
> +				       4600 4
> +				       4800 5
> +				       4900 6
> +				       5000 7 >;
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/fan-speed-120.dtsi b/arch/arm/boot/dts/synology/fan-speed-120.dtsi
> new file mode 100644
> index 000000000000..90157070492c
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-speed-120.dtsi
> @@ -0,0 +1,20 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	gpio_fan {
> +		gpio-fan,speed-map = <    0 0
> +				       2500 1
> +				       2700 2
> +				       3000 4
> +				       3600 3
> +				       3800 5
> +				       3900 6
> +				       4300 7 >;
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/fan-speed-150.dtsi b/arch/arm/boot/dts/synology/fan-speed-150.dtsi
> new file mode 100644
> index 000000000000..6abc36915886
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/fan-speed-150.dtsi
> @@ -0,0 +1,20 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	gpio_fan {
> +		gpio-fan,speed-map = <    0 0
> +				       2200 1
> +				       2500 2
> +				       3000 4
> +				       3300 3
> +				       3700 5
> +				       3800 6
> +				       4200 7 >;
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-leds-20.dtsi b/arch/arm/boot/dts/synology/hdd-leds-20.dtsi
> new file mode 100644
> index 000000000000..e6663ea7014c
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-leds-20.dtsi
> @@ -0,0 +1,90 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_led_20: pmx-led-20 {
> +				marvell,pins = "mpp20";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_21: pmx-led-21 {
> +				marvell,pins = "mpp21";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_22: pmx-led-22 {
> +				marvell,pins = "mpp22";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_23: pmx-led-23 {
> +				marvell,pins = "mpp23";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_24: pmx-led-24 {
> +				marvell,pins = "mpp24";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_25: pmx-led-25 {
> +				marvell,pins = "mpp25";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_26: pmx-led-26 {
> +				marvell,pins = "mpp26";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_27: pmx-led-27 {
> +				marvell,pins = "mpp27";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_28: pmx-led-28 {
> +				marvell,pins = "mpp28";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +		pinctrl-0 = <&pmx_led_20 &pmx_led_21 &pmx_led_22
> +			     &pmx_led_23 &pmx_led_24 &pmx_led_25
> +			     &pmx_led_26 &pmx_led_27>;
> +		pinctrl-names = "default";
> +		hdd1-green {
> +			label = "synology:green:hdd1";
> +			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd1-amber {
> +			label = "synology:amber:hdd1";
> +			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-green {
> +			label = "synology:green:hdd2";
> +			gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-amber {
> +			label = "synology:amber:hdd2";
> +			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd3-green {
> +			label = "synology:green:hdd3";
> +			gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd3-amber {
> +			label = "synology:amber:hdd3";
> +			gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd4-green {
> +			label = "synology:green:hdd4";
> +			gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd4-amber {
> +			label = "synology:amber:hdd4";
> +			gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-leds-21-1.dtsi b/arch/arm/boot/dts/synology/hdd-leds-21-1.dtsi
> new file mode 100644
> index 000000000000..034323f9ffb0
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-leds-21-1.dtsi
> @@ -0,0 +1,36 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_led_21: pmx-led-21 {
> +				marvell,pins = "mpp21";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_23: pmx-led-23 {
> +				marvell,pins = "mpp23";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +		pinctrl-0 = <&pmx_led_21 &pmx_led_23>;
> +		pinctrl-names = "default";
> +		hdd1-green {
> +			label = "synology:green:hdd1";
> +			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd1-amber {
> +			label = "synology:amber:hdd1";
> +			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-leds-21-2.dtsi b/arch/arm/boot/dts/synology/hdd-leds-21-2.dtsi
> new file mode 100644
> index 000000000000..446a28f2200b
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-leds-21-2.dtsi
> @@ -0,0 +1,52 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_led_20: pmx-led-20 {
> +				marvell,pins = "mpp20";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_21: pmx-led-21 {
> +				marvell,pins = "mpp21";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_22: pmx-led-22 {
> +				marvell,pins = "mpp22";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_23: pmx-led-23 {
> +				marvell,pins = "mpp23";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +		pinctrl-0 = <&pmx_led_21 &pmx_led_23 &pmx_led_20 &pmx_led_22>;
> +		pinctrl-names = "default";
> +		hdd1-green {
> +			label = "synology:green:hdd1";
> +			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd1-amber {
> +			label = "synology:amber:hdd1";
> +			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-green {
> +			label = "synology:green:hdd2";
> +			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-amber {
> +			label = "synology:amber:hdd2";
> +			gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-leds-36.dtsi b/arch/arm/boot/dts/synology/hdd-leds-36.dtsi
> new file mode 100644
> index 000000000000..9541c0c943e6
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-leds-36.dtsi
> @@ -0,0 +1,103 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_led_36: pmx-led-36 {
> +				marvell,pins = "mpp36";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_37: pmx-led-37 {
> +				marvell,pins = "mpp37";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_38: pmx-led-38 {
> +				marvell,pins = "mpp38";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_39: pmx-led-39 {
> +				marvell,pins = "mpp39";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_40: pmx-led-40 {
> +				marvell,pins = "mpp40";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_41: pmx-led-41 {
> +				marvell,pins = "mpp41";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_42: pmx-led-42 {
> +				marvell,pins = "mpp42";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_43: pmx-led-43 {
> +				marvell,pins = "mpp43";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_44: pmx-led-44 {
> +				marvell,pins = "mpp44";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_45: pmx-led-45 {
> +				marvell,pins = "mpp45";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +		pinctrl-0 = <&pmx_led_36 &pmx_led_37 &pmx_led_38
> +			     &pmx_led_39 &pmx_led_40 &pmx_led_41
> +			     &pmx_led_42 &pmx_led_43 &pmx_led_44
> +			     &pmx_led_45>;
> +		pinctrl-names = "default";
> +		hdd1-green {
> +			label = "synology:green:hdd1";
> +			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd1-amber {
> +			label = "synology:amber:hdd1";
> +			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-green {
> +			label = "synology:green:hdd2";
> +			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-amber {
> +			label = "synology:amber:hdd2";
> +			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd3-green {
> +			label = "synology:green:hdd3";
> +			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd3-amber {
> +			label = "synology:amber:hdd3";
> +			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd4-green {
> +			label = "synology:green:hdd4";
> +			gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd4-amber {
> +			label = "synology:amber:hdd4";
> +			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd5-green {
> +			label = "synology:green:hdd5";
> +			gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd5-amber {
> +			label = "synology:amber:hdd5";
> +			gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-leds-38.dtsi b/arch/arm/boot/dts/synology/hdd-leds-38.dtsi
> new file mode 100644
> index 000000000000..d2fe351a0808
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-leds-38.dtsi
> @@ -0,0 +1,52 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_led_38: pmx-led-38 {
> +				marvell,pins = "mpp38";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_39: pmx-led-39 {
> +				marvell,pins = "mpp39";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_36: pmx-led-36 {
> +				marvell,pins = "mpp36";
> +				marvell,function = "gpio";
> +			};
> +			pmx_led_37: pmx-led-37 {
> +				marvell,pins = "mpp37";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +		pinctrl-0 = <&pmx_led_38 &pmx_led_39 &pmx_led_36 &pmx_led_37>;
> +		pinctrl-names = "default";
> +		hdd1-green {
> +			label = "synology:green:hdd1";
> +			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd1-amber {
> +			label = "synology:amber:hdd1";
> +			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-green {
> +			label = "synology:green:hdd2";
> +			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
> +		};
> +		hdd2-amber {
> +			label = "synology:amber:hdd2";
> +			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-power-29.dtsi b/arch/arm/boot/dts/synology/hdd-power-29.dtsi
> new file mode 100644
> index 000000000000..8b08c86ab942
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-power-29.dtsi
> @@ -0,0 +1,56 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_hdd1_pwr_29: pmx-hdd1-pwr-29 {
> +				marvell,pins = "mpp29";
> +				marvell,function = "gpio";
> +			};
> +			pmx_hdd2_pwr_31: pmx-hdd2-pwr-31 {
> +				marvell,pins = "mpp31";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_hdd1_pwr_29 &pmx_hdd2_pwr_31>;
> +		pinctrl-names = "default";
> +
> +		hdd1_power: regulator at 1 {
> +			compatible = "regulator-fixed";
> +			reg = <1>;
> +			regulator-name = "hdd1power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
> +		};
> +		hdd2_power: regulator at 2 {
> +			compatible = "regulator-fixed";
> +			reg = <2>;
> +			regulator-name = "hdd2power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-power-30-1.dtsi b/arch/arm/boot/dts/synology/hdd-power-30-1.dtsi
> new file mode 100644
> index 000000000000..b0998d4e231f
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-power-30-1.dtsi
> @@ -0,0 +1,40 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_hdd1_pwr_30: pmx-hdd-pwr-30 {
> +				marvell,pins = "mpp30";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_hdd1_pwr_30>;
> +		pinctrl-names = "default";
> +
> +		hdd1_power: regulator at 1 {
> +			compatible = "regulator-fixed";
> +			reg = <1>;
> +			regulator-name = "hdd1power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-power-30-2.dtsi b/arch/arm/boot/dts/synology/hdd-power-30-2.dtsi
> new file mode 100644
> index 000000000000..766e6352d5af
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-power-30-2.dtsi
> @@ -0,0 +1,56 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_hdd1_pwr_30: pmx-hdd-pwr-30 {
> +				marvell,pins = "mpp30";
> +				marvell,function = "gpio";
> +			};
> +			pmx_hdd2_pwr_34: pmx-hdd2-pwr-34 {
> +				marvell,pins = "mpp34";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34>;
> +		pinctrl-names = "default";
> +
> +		hdd1_power: regulator at 1 {
> +			compatible = "regulator-fixed";
> +			reg = <1>;
> +			regulator-name = "hdd1power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
> +		};
> +		hdd2_power: regulator at 2 {
> +			compatible = "regulator-fixed";
> +			reg = <2>;
> +			regulator-name = "hdd2power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-power-30-4.dtsi b/arch/arm/boot/dts/synology/hdd-power-30-4.dtsi
> new file mode 100644
> index 000000000000..5bbced207965
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-power-30-4.dtsi
> @@ -0,0 +1,89 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_hdd1_pwr_30: pmx-hdd-pwr-30 {
> +				marvell,pins = "mpp30";
> +				marvell,function = "gpio";
> +			};
> +			pmx_hdd2_pwr_34: pmx-hdd2-pwr-34 {
> +				marvell,pins = "mpp34";
> +				marvell,function = "gpio";
> +			};
> +			pmx_hdd3_pwr_44: pmx-hdd3-pwr-44 {
> +				marvell,pins = "mpp44";
> +				marvell,function = "gpio";
> +			};
> +			pmx_hdd4_pwr_45: pmx-hdd4-pwr-45 {
> +				marvell,pins = "mpp45";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34
> +			     &pmx_hdd3_pwr_44 &pmx_hdd4_pwr_45>;
> +		pinctrl-names = "default";
> +
> +		hdd1_power: regulator at 1 {
> +			compatible = "regulator-fixed";
> +			reg = <1>;
> +			regulator-name = "hdd1power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
> +		};
> +		hdd2_power: regulator at 2 {
> +			compatible = "regulator-fixed";
> +			reg = <2>;
> +			regulator-name = "hdd2power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
> +		};
> +		hdd3_power: regulator at 3 {
> +			compatible = "regulator-fixed";
> +			reg = <3>;
> +			regulator-name = "hdd3power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
> +		};
> +		hdd4_power: regulator at 4 {
> +			compatible = "regulator-fixed";
> +			reg = <4>;
> +			regulator-name = "hdd3power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio1 32 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-power-31.dtsi b/arch/arm/boot/dts/synology/hdd-power-31.dtsi
> new file mode 100644
> index 000000000000..0774ecdcaf64
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-power-31.dtsi
> @@ -0,0 +1,40 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_hdd2_pwr_31: pmx-hdd2-pwr-31 {
> +				marvell,pins = "mpp31";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_hdd2_pwr_31>;
> +		pinctrl-names = "default";
> +
> +		hdd2_power: regulator at 1 {
> +			compatible = "regulator-fixed";
> +			reg = <1>;
> +			regulator-name = "hdd2power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/hdd-power-34.dtsi b/arch/arm/boot/dts/synology/hdd-power-34.dtsi
> new file mode 100644
> index 000000000000..d90becf582f1
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/hdd-power-34.dtsi
> @@ -0,0 +1,73 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		pinctrl: pinctrl at 10000 {
> +
> +			pmx_hdd2_pwr_34: pmx-hdd2-pwr-34 {
> +				marvell,pins = "mpp34";
> +				marvell,function = "gpio";
> +			};
> +			pmx_hdd3_pwr_44: pmx-hdd3-pwr-44 {
> +				marvell,pins = "mpp44";
> +				marvell,function = "gpio";
> +			};
> +			pmx_hdd4_pwr_45: pmx-hdd4-pwr-45 {
> +				marvell,pins = "mpp45";
> +				marvell,function = "gpio";
> +			};
> +		};
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_hdd2_pwr_34 &pmx_hdd3_pwr_44
> +			     &pmx_hdd4_pwr_45>;
> +		pinctrl-names = "default";
> +
> +		hdd2_power: regulator at 2 {
> +			compatible = "regulator-fixed";
> +			reg = <2>;
> +			regulator-name = "hdd2power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
> +		};
> +		hdd3_power: regulator at 3 {
> +			compatible = "regulator-fixed";
> +			reg = <3>;
> +			regulator-name = "hdd3power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
> +		};
> +		hdd4_power: regulator at 4 {
> +			compatible = "regulator-fixed";
> +			reg = <4>;
> +			regulator-name = "hdd3power";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			startup-delay-us = <5000000>;
> +			gpio = <&gpio1 32 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/i2c-rtc-ricoh.dtsi b/arch/arm/boot/dts/synology/i2c-rtc-ricoh.dtsi
> new file mode 100644
> index 000000000000..920ad215462d
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/i2c-rtc-ricoh.dtsi
> @@ -0,0 +1,18 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		i2c at 11000 {
> +			rs5c372: rs5c372 at 32 {
> +				compatible = "ricoh,rs5c372a";
> +				reg = <0x32>;
> +			};
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/i2c-rtc-seiko.dtsi b/arch/arm/boot/dts/synology/i2c-rtc-seiko.dtsi
> new file mode 100644
> index 000000000000..4b5054bb4a87
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/i2c-rtc-seiko.dtsi
> @@ -0,0 +1,18 @@
> +/*
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	ocp at f1000000 {
> +		i2c at 11000 {
> +			s35390a: s35390a at 30 {
> +				compatible = "sii,s35390a";
> +				reg = <0x30>;
> +			};
> +		};
> +	};
> +};
> \ No newline at end of file
> diff --git a/arch/arm/boot/dts/synology/pcie-2.dtsi b/arch/arm/boot/dts/synology/pcie-2.dtsi
> new file mode 100644
> index 000000000000..e34ebb5515c2
> --- /dev/null
> +++ b/arch/arm/boot/dts/synology/pcie-2.dtsi
> @@ -0,0 +1,19 @@
> +/*
> + * Nodes which are common to all Synology devices
> + *
> + * Andrew Lunn <andrew@lunn.ch>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> +	mbus {
> +		pcie-controller {
> +			pcie at 2,0 {
> +				status = "okay";
> +			};
> +		};
> +	};
> +};
> \ No newline at end of file
> -- 
> 1.7.10.4
> 

^ permalink raw reply

* [PATCH 2/4] DT: Vendor prefixes: Add ricoh, ssi and synology
From: Rob Herring @ 2014-02-06 15:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391634309-3123-3-git-send-email-andrew@lunn.ch>

On Wed, Feb 5, 2014 at 3:05 PM, Andrew Lunn <andrew@lunn.ch> wrote:
> The following patches make use of vendor names ricoh, ssi and
> synology.  Add them to the vendor prefix list.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.txt |    3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 3f900cd51bf0..1629e8f33578 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -69,6 +69,7 @@ ralink        Mediatek/Ralink Technology Corp.
>  ramtron        Ramtron International
>  realtek Realtek Semiconductor Corp.
>  renesas        Renesas Electronics Corporation
> +ricoh  Richoh Co. Ltd.

This should be "ricoy" to follow the stock ticker symbol.

Rob

^ permalink raw reply

* [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
From: Lars-Peter Clausen @ 2014-02-06 15:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CA+mB=1JX5K9Cu=9WGyr_e9tUtVz6ypT9UxhJU9BNJbQA9eaRKA@mail.gmail.com>

On 02/06/2014 02:34 PM, Srikanth Thokala wrote:
> On Wed, Feb 5, 2014 at 10:00 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
>> On 02/05/2014 05:25 PM, Srikanth Thokala wrote:
>>>
>>> On Fri, Jan 31, 2014 at 12:21 PM, Srikanth Thokala <sthokal@xilinx.com>
>>> wrote:
>>>>
>>>> Hi Vinod,
>>>>
>>>> On Tue, Jan 28, 2014 at 8:43 AM, Vinod Koul <vinod.koul@intel.com> wrote:
>>>>>
>>>>> On Mon, Jan 27, 2014 at 06:42:36PM +0530, Srikanth Thokala wrote:
>>>>>>
>>>>>> Hi Lars/Vinod,
>>>>>>>>
>>>>>>>> The question here i think would be waht this device supports? Is the
>>>>>>>> hardware
>>>>>>>> capable of doing interleaved transfers, then would make sense.
>>>>>>>
>>>>>>>
>>>>>>> The hardware does 2D transfers. The parameters for a transfer are
>>>>>>> height,
>>>>>>> width and stride. That's only a subset of what interleaved transfers
>>>>>>> can be
>>>>>>> (xt->num_frames must be one for 2d transfers). But if I remember
>>>>>>> correctly
>>>>>>> there has been some discussion on this in the past and the result of
>>>>>>> that
>>>>>>> discussion was that using interleaved transfers for 2D transfers is
>>>>>>> preferred over adding a custom API for 2D transfers.
>>>>>>
>>>>>>
>>>>>> I went through the prep_interleaved_dma API and I see only one
>>>>>> descriptor
>>>>>> is prepared per API call (i.e. per frame).  As our IP supports upto 16
>>>>>> frame
>>>>>> buffers (can be more in future), isn't it less efficient compared to
>>>>>> the
>>>>>> prep_slave_sg where we get a single sg list and can prepare all the
>>>>>> descriptors
>>>>>> (of non-contiguous buffers) in one go?  Correct me, if am wrong and let
>>>>>> me
>>>>>> know your opinions.
>>>>>
>>>>> Well the descriptor maybe one, but that can represent multiple frames,
>>>>> for
>>>>> example 16 as in your case. Can you read up the documentation of how
>>>>> multiple
>>>>> frames are passed. Pls see include/linux/dmaengine.h
>>>>>
>>>>> /**
>>>>>    * Interleaved Transfer Request
>>>>>    * ----------------------------
>>>>>    * A chunk is collection of contiguous bytes to be transfered.
>>>>>    * The gap(in bytes) between two chunks is called inter-chunk-gap(ICG).
>>>>>    * ICGs may or maynot change between chunks.
>>>>>    * A FRAME is the smallest series of contiguous {chunk,icg} pairs,
>>>>>    *  that when repeated an integral number of times, specifies the
>>>>> transfer.
>>>>>    * A transfer template is specification of a Frame, the number of times
>>>>>    *  it is to be repeated and other per-transfer attributes.
>>>>>    *
>>>>>    * Practically, a client driver would have ready a template for each
>>>>>    *  type of transfer it is going to need during its lifetime and
>>>>>    *  set only 'src_start' and 'dst_start' before submitting the
>>>>> requests.
>>>>>    *
>>>>>    *
>>>>>    *  |      Frame-1        |       Frame-2       | ~ |
>>>>> Frame-'numf'  |
>>>>>    *  |====....==.===...=...|====....==.===...=...| ~
>>>>> |====....==.===...=...|
>>>>>    *
>>>>>    *    ==  Chunk size
>>>>>    *    ... ICG
>>>>>    */
>>>>
>>>>
>>>> Yes, it can handle multiple frames specified by 'numf' each of size
>>>> 'frame_size * sgl[0].size'.
>>>> But, I see it only works if all the frames' memory is contiguous and
>>>> in this case we
>>>> can just increment 'src_start' by the total frame size 'numf' number
>>>> of times to fill in
>>>> for each HW descriptor (each frame is one HW descriptor).  So, there
>>>> is no issue when the
>>>> memory is contiguous.  If the frames are non contiguous, we have to
>>>> call this API for each
>>>> frame (hence for each descriptor), as the src_start for each frame is
>>>> different.  Is it correct?
>>>>
>>>> FYI: This hardware has an inbuilt Scatter-Gather engine.
>>>>
>>>
>>> Ping?
>>
>>
>> If you want to submit multiple frames at once I think you should look at how
>> the current dmaengine API can be extended to allow that. And also provide an
>> explanation on how this is superior over submitting them one by one.
>
>
> Sure.  I would start with explaning the current implementation of this driver.
>
> Using prep_slave_sg(), we can define multiple segments in a
> async_tx_descriptor where each frame is defined by a segment (a sg
> list entry).  So, the slave device could DMA the data (of multiple
> frames) with a descriptor by calling tx_submit in a transaction i.e.,
>
> prep_slave_sg(16)  -> tx_submit(1) -> interrupt  (16 frames)
>
> Using interleaved_dma(), we could not divide into segments when we
> have scattered memory (for the reasons mentioned in above thread).
> This implies we are restricting the slave device to process frame by
> frame i.e.,
>
> interleaved_dma(1) -> tx_submit(1) -> interrupt -> interleaved_dma(2)
> -> tx_submit (2) -> interrupt -> ........ tx_submit(16) -> interrupt
>

The API allows you to create and submit multiple interleaved descriptors 
before you have to issue them.

interleaved_dma(1) -> tx_submit(1) -> interleaved_dma(2) -> tx_submit(2) -> 
... -> issue_pending() -> interrupt

> This implementation makes the hardware to wait until the next frame is
> submitted.
>
> To overcome this, I feel it would be a good option if we could extend
> interleaved_dma template to modify src_start/dest_start to be a
> pointer to an array of addresses.  Here, number of addresses will be
> defined by numf. The other option would be to include scatterlist in
> the interleaved template. This way we can handle scattered memory
> using this API.

Each "frame" in a interleaved transfer describes a single line in your video 
frame (size = width, icg = stride). numf is the number of lines per video 
frame. So the suggested change does not make that much sense. If you want to 
submit multiple video frames in one batch the best option is in my opinion 
to allow to pass an array of dma_interleaved_template structs instead of a 
single one.

- Lars

>
> Srikanth
>
>>
>> - Lars
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" 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 1/2] PPC: powernv: remove redundant cpuidle_idle_call()
From: Preeti U Murthy @ 2014-02-06 15:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391696188-14540-1-git-send-email-nicolas.pitre@linaro.org>

On 02/06/2014 07:46 PM, Nicolas Pitre wrote:
> The core idle loop now takes care of it.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  arch/powerpc/platforms/powernv/setup.c | 13 +------------
>  1 file changed, 1 insertion(+), 12 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
> index 21166f65c9..a932feb290 100644
> --- a/arch/powerpc/platforms/powernv/setup.c
> +++ b/arch/powerpc/platforms/powernv/setup.c
> @@ -26,7 +26,6 @@
>  #include <linux/of_fdt.h>
>  #include <linux/interrupt.h>
>  #include <linux/bug.h>
> -#include <linux/cpuidle.h>
> 
>  #include <asm/machdep.h>
>  #include <asm/firmware.h>
> @@ -217,16 +216,6 @@ static int __init pnv_probe(void)
>  	return 1;
>  }
> 
> -void powernv_idle(void)
> -{
> -	/* Hook to cpuidle framework if available, else
> -	 * call on default platform idle code
> -	 */
> -	if (cpuidle_idle_call()) {
> -		power7_idle();
> -	}
> -}
> -
>  define_machine(powernv) {
>  	.name			= "PowerNV",
>  	.probe			= pnv_probe,
> @@ -236,7 +225,7 @@ define_machine(powernv) {
>  	.show_cpuinfo		= pnv_show_cpuinfo,
>  	.progress		= pnv_progress,
>  	.machine_shutdown	= pnv_shutdown,
> -	.power_save             = powernv_idle,
> +	.power_save             = power7_idle,
>  	.calibrate_decr		= generic_calibrate_decr,
>  #ifdef CONFIG_KEXEC
>  	.kexec_cpu_down		= pnv_kexec_cpu_down,
> 

Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>

^ permalink raw reply

* [PATCH 2/2] ARM64: powernv: remove redundant cpuidle_idle_call()
From: Preeti U Murthy @ 2014-02-06 15:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391696188-14540-2-git-send-email-nicolas.pitre@linaro.org>

Hi Nicolas,

powernv in the subject of the patch?

Regards
Preeti U Murthy
On 02/06/2014 07:46 PM, Nicolas Pitre wrote:
> The core idle loop now takes care of it.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  arch/arm64/kernel/process.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 1c0a9be2ff..9cce0098f4 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -33,7 +33,6 @@
>  #include <linux/kallsyms.h>
>  #include <linux/init.h>
>  #include <linux/cpu.h>
> -#include <linux/cpuidle.h>
>  #include <linux/elfcore.h>
>  #include <linux/pm.h>
>  #include <linux/tick.h>
> @@ -94,10 +93,8 @@ void arch_cpu_idle(void)
>  	 * This should do all the clock switching and wait for interrupt
>  	 * tricks
>  	 */
> -	if (cpuidle_idle_call()) {
> -		cpu_do_idle();
> -		local_irq_enable();
> -	}
> +	cpu_do_idle();
> +	local_irq_enable();
>  }
> 
>  #ifdef CONFIG_HOTPLUG_CPU
> 

^ permalink raw reply

* [PATCH 4/4] ARM: Kirkwood: Add support for many Synology NAS devices
From: Andrew Lunn @ 2014-02-06 16:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140206153939.GD8533@titan.lakedaemon.net>

On Thu, Feb 06, 2014 at 10:39:39AM -0500, Jason Cooper wrote:
> 
> + devicetree ML, DT maintainers
> 
> On Wed, Feb 05, 2014 at 10:05:09PM +0100, Andrew Lunn wrote:
> > Add device tree fragments and files to support many of the kirkwood
> > based Synology NAS devices. This is a translation of the board setup
> > file maintained by Ben Peddell <klightspeed@killerwolves.net>
> > 
> > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > Tested by Ben Peddell <klightspeed@killerwolves.net>
> > cc: Ben Peddell <klightspeed@killerwolves.net>
> > ---
> > 
> > v2:
> > Fix gpio's which should be gpo.
> > Rebase onto v3-14-rc1
> > Update RTC nodes with vendor name.
> > Update SPI flash node with vendor name.
> > ---
> >  arch/arm/boot/dts/Makefile                     |   15 ++++
> >  arch/arm/boot/dts/kirkwood-ds109.dts           |   33 +++++++
> >  arch/arm/boot/dts/kirkwood-ds110jv10.dts       |   33 +++++++
> >  arch/arm/boot/dts/kirkwood-ds111.dts           |   33 +++++++
> >  arch/arm/boot/dts/kirkwood-ds112.dts           |   34 +++++++
> >  arch/arm/boot/dts/kirkwood-ds209.dts           |   33 +++++++
> >  arch/arm/boot/dts/kirkwood-ds210.dts           |   35 ++++++++
> >  arch/arm/boot/dts/kirkwood-ds212.dts           |   37 ++++++++
> >  arch/arm/boot/dts/kirkwood-ds212j.dts          |   34 +++++++
> >  arch/arm/boot/dts/kirkwood-ds409.dts           |   34 +++++++
> >  arch/arm/boot/dts/kirkwood-ds409slim.dts       |   32 +++++++
> >  arch/arm/boot/dts/kirkwood-ds411.dts           |   35 ++++++++
> >  arch/arm/boot/dts/kirkwood-ds411j.dts          |   34 +++++++
> >  arch/arm/boot/dts/kirkwood-ds411slim.dts       |   34 +++++++
> >  arch/arm/boot/dts/kirkwood-rs212.dts           |   34 +++++++
> >  arch/arm/boot/dts/kirkwood-rs409.dts           |   33 +++++++
> >  arch/arm/boot/dts/kirkwood-rs411.dts           |   34 +++++++
> >  arch/arm/boot/dts/synology/alarm-led-12.dtsi   |   28 ++++++
> >  arch/arm/boot/dts/synology/common.dtsi         |  112 ++++++++++++++++++++++++
> >  arch/arm/boot/dts/synology/ethernet-1.dtsi     |   15 ++++
> >  arch/arm/boot/dts/synology/fan-alarm-18.dtsi   |   22 +++++
> >  arch/arm/boot/dts/synology/fan-alarm-35-1.dtsi |   22 +++++
> >  arch/arm/boot/dts/synology/fan-alarm-35-3.dtsi |   32 +++++++
> >  arch/arm/boot/dts/synology/fan-gpios-15.dtsi   |   34 +++++++
> >  arch/arm/boot/dts/synology/fan-gpios-32.dtsi   |   34 +++++++
> >  arch/arm/boot/dts/synology/fan-speed-100.dtsi  |   20 +++++
> >  arch/arm/boot/dts/synology/fan-speed-120.dtsi  |   20 +++++
> >  arch/arm/boot/dts/synology/fan-speed-150.dtsi  |   20 +++++
> >  arch/arm/boot/dts/synology/hdd-leds-20.dtsi    |   90 +++++++++++++++++++
> >  arch/arm/boot/dts/synology/hdd-leds-21-1.dtsi  |   36 ++++++++
> >  arch/arm/boot/dts/synology/hdd-leds-21-2.dtsi  |   52 +++++++++++
> >  arch/arm/boot/dts/synology/hdd-leds-36.dtsi    |  103 ++++++++++++++++++++++
> >  arch/arm/boot/dts/synology/hdd-leds-38.dtsi    |   52 +++++++++++
> >  arch/arm/boot/dts/synology/hdd-power-29.dtsi   |   56 ++++++++++++
> >  arch/arm/boot/dts/synology/hdd-power-30-1.dtsi |   40 +++++++++
> >  arch/arm/boot/dts/synology/hdd-power-30-2.dtsi |   56 ++++++++++++
> >  arch/arm/boot/dts/synology/hdd-power-30-4.dtsi |   89 +++++++++++++++++++
> >  arch/arm/boot/dts/synology/hdd-power-31.dtsi   |   40 +++++++++
> >  arch/arm/boot/dts/synology/hdd-power-34.dtsi   |   73 +++++++++++++++
> >  arch/arm/boot/dts/synology/i2c-rtc-ricoh.dtsi  |   18 ++++
> >  arch/arm/boot/dts/synology/i2c-rtc-seiko.dtsi  |   18 ++++
> >  arch/arm/boot/dts/synology/pcie-2.dtsi         |   19 ++++
> >  42 files changed, 1658 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds109.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds110jv10.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds111.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds112.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds209.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds210.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds212.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds212j.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds409.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds409slim.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds411.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds411j.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-ds411slim.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-rs212.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-rs409.dts
> >  create mode 100644 arch/arm/boot/dts/kirkwood-rs411.dts
> >  create mode 100644 arch/arm/boot/dts/synology/alarm-led-12.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/common.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/ethernet-1.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-alarm-18.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-alarm-35-1.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-alarm-35-3.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-gpios-15.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-gpios-32.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-speed-100.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-speed-120.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/fan-speed-150.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-20.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-21-1.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-21-2.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-36.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-leds-38.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-power-29.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-power-30-1.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-power-30-2.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-power-30-4.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-power-31.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/hdd-power-34.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/i2c-rtc-ricoh.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/i2c-rtc-seiko.dtsi
> >  create mode 100644 arch/arm/boot/dts/synology/pcie-2.dtsi
> 
> Holy sh*t!  I know we're adding 15 boards

More than 15 actually. Most .dts files support multiple devices. So
there should be about 30 devices supported by these .dts files.

, but this is, imho,
> over-fragmenting.  I'm sure there's a reason you chose this path, but
> you haven't explained why in your commit log. So I'm left guessing...

Synology seem to build there devices like lego. They have two
different RTC blocks. They have three different fan alarm blocks, four
different led blocks, etc. And to build a product, the just select a
group of blocks and put them together.

The board setup code which Ben Peddell wrote has a somewhat similar
structure:

http://klightspeed.killerwolves.net/synology/linux-3.4-synology-0.1.patch

It has a set of functions which add platform devices. And a table
driven piece of code which based on the product name calls these
functions to add the needed platform devices. Take a look at the table
to get a better idea of the re-use factor of the blocks.

In this DT version, i have a dtsi file for each function, and a dti
file for each table entry.

I will add to the changelog in the next version.

  Andrew

^ permalink raw reply

* [PATCH] backlight: add PWM dependencies
From: Arnd Bergmann @ 2014-02-06 16:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <000001cf230c$60ec1ca0$22c455e0$%han@samsung.com>

On Thursday 06 February 2014, Jingoo Han wrote:
> In the case of "CONFIG_HAVE_PWM=y && CONFIG_PWM=n", it makes
> the problem.
> 
> The HAVE_PWM symbol is only for legacy platforms that provide
> the PWM API without using the generic framework. PXA looks to
> use the generic PWM framework. Then, how about removing
> "select HAVE_PWM" from PXA as below?
> 

I think this is correct, but we may need additional patches. I notice
that INPUT_MAX8997_HAPTIC and INPUT_PWM_BEEPER have a dependency on
HAVE_PWM at the moment, so those two drivers become impossible
to select after your change.

There is also one use of HAVE_PWM outside of PXA, for ARCH_LPC32XX.
This one seems to have the same problem.

Finally, I have recently encountered a couple of drivers
(BACKLIGHT_LM3630A, BACKLIGHT_LP855X, BACKLIGHT_LP8788) that use
the PWM interfaces but are missing a 'depends on PWM'. This is
strictly speaking a different problem, but we could try to solve
it at the same time.

	Arnd

^ permalink raw reply

* [PATCH 2/2] ARM64: powernv: remove redundant cpuidle_idle_call()
From: Nicolas Pitre @ 2014-02-06 16:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F3B17E.4040209@linux.vnet.ibm.com>

On Thu, 6 Feb 2014, Preeti U Murthy wrote:

> Hi Nicolas,
> 
> powernv in the subject of the patch?

Crap.  You're right.

That's what you get when posting patches while attending a meeting.



> 
> Regards
> Preeti U Murthy
> On 02/06/2014 07:46 PM, Nicolas Pitre wrote:
> > The core idle loop now takes care of it.
> > 
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > ---
> >  arch/arm64/kernel/process.c | 7 ++-----
> >  1 file changed, 2 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> > index 1c0a9be2ff..9cce0098f4 100644
> > --- a/arch/arm64/kernel/process.c
> > +++ b/arch/arm64/kernel/process.c
> > @@ -33,7 +33,6 @@
> >  #include <linux/kallsyms.h>
> >  #include <linux/init.h>
> >  #include <linux/cpu.h>
> > -#include <linux/cpuidle.h>
> >  #include <linux/elfcore.h>
> >  #include <linux/pm.h>
> >  #include <linux/tick.h>
> > @@ -94,10 +93,8 @@ void arch_cpu_idle(void)
> >  	 * This should do all the clock switching and wait for interrupt
> >  	 * tricks
> >  	 */
> > -	if (cpuidle_idle_call()) {
> > -		cpu_do_idle();
> > -		local_irq_enable();
> > -	}
> > +	cpu_do_idle();
> > +	local_irq_enable();
> >  }
> > 
> >  #ifdef CONFIG_HOTPLUG_CPU
> > 
> 

^ permalink raw reply

* [RFC PATCH V2 0/4] get_user_pages_fast for ARM and ARM64
From: Steve Capper @ 2014-02-06 16:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,
This RFC series implements get_user_pages_fast and __get_user_pages_fast.
These are required for Transparent HugePages to function correctly, as
a futex on a THP tail will otherwise result in an infinite loop (due to
the core implementation of __get_user_pages_fast always returning 0).
This series may also be beneficial for direct-IO heavy workloads and
certain KVM workloads.
 
Previous RFCs for fast_gup on arm have included one from Chanho Park:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-April/162115.html

one from Zi Shen Lim:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-October/202133.html

and my RFC V1:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-October/205951.html

The main issues with previous RFCs have been in the mechanisms used to
prevent page table pages from being freed from under the fast_gup
walker. Some other architectures disable interrupts in the fast_gup
walker, and then rely on the fact that TLB invalidations require IPIs;
thus the page table freeing code is blocked by the walker. Some ARM
platforms, however, have hardware broadcasts for TLB invalidation, so
do not always require IPIs to flush TLBs. Some extra logic is therefore
required to protect the fast_gup walker on ARM.

My previous RFC attempted to protect the fast_gup walker with atomics,
but this led to performance degradation.

This RFC V2 instead uses the RCU scheduler logic from PowerPC to protect
the fast_gup walker. All page table pages belonging to an address space
with more than one user are batched together and freed from a delayed
call_rcu_sched routine. Disabling interrupts will block the RCU delayed
scheduler and prevent the page table pages from being freed from under
the fast_gup walker. If there is not enough memory to batch the page
tables together (which is very rare), then IPIs are raised individually
instead.

The RCU logic is activated by enabling HAVE_RCU_TABLE_FREE, and some
modifications are made to the mmu_gather code in ARM and ARM64 to plumb
it in. On ARM64, we could probably go one step further and switch to
the generic mmu_gather code too.

THP splitting is made to broadcast an IPI as we need to block these
completely when the fast_gup walker is active. As THP splits are
relatively rare (on my machine with 22 days uptime I count 27678), I do
not expect these IPIs to cause any performance issues.

I have tested the series using the Fast Model for ARM64 and an Arndale
Board. A series of hackbench runs on the Arndale did not turn up any
performance degradation with this patch set applied.

This series applies to 3.13, but has also been tested on 3.14-rc1.

I would really appreciate any comments and/or testers!

Cheers,
-- 
Steve

Steve Capper (4):
  arm: mm: Enable HAVE_RCU_TABLE_FREE logic
  arm: mm: implement get_user_pages_fast
  arm64: mm: Enable HAVE_RCU_TABLE_FREE logic
  arm64: mm: implement get_user_pages_fast

 arch/arm/Kconfig                      |   1 +
 arch/arm/include/asm/pgtable-3level.h |   6 +
 arch/arm/include/asm/tlb.h            |  38 ++++-
 arch/arm/mm/Makefile                  |   2 +-
 arch/arm/mm/gup.c                     | 251 ++++++++++++++++++++++++++++
 arch/arm64/Kconfig                    |   1 +
 arch/arm64/include/asm/pgtable.h      |   4 +
 arch/arm64/include/asm/tlb.h          |  27 +++-
 arch/arm64/mm/Makefile                |   2 +-
 arch/arm64/mm/gup.c                   | 297 ++++++++++++++++++++++++++++++++++
 10 files changed, 623 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/mm/gup.c
 create mode 100644 arch/arm64/mm/gup.c

-- 
1.8.1.4

^ permalink raw reply

* [RFC PATCH V2 1/4] arm: mm: Enable HAVE_RCU_TABLE_FREE logic
From: Steve Capper @ 2014-02-06 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391703531-12845-1-git-send-email-steve.capper@linaro.org>

In order to implement fast_get_user_pages we need to ensure that the
page table walker is protected from page table pages being freed from
under it.

One way to achieve this is to have the walker disable interrupts, and
rely on IPIs from the TLB flushing code blocking before the page table
pages are freed.

On some ARM platforms we have hardware TLB invalidation, thus the TLB
flushing code won't necessarily broadcast IPIs. Also spuriously
broadcasting IPIs can hurt system performance if done too often.

This problem has already been solved on PowerPC and Sparc by batching
up page table pages belonging to more than one mm_user, then scheduling
an rcu_sched callback to free the pages. If one were to disable
interrupts, that would block the page table pages being freed. This
logic has also been promoted to core code and is activated when one
enables HAVE_RCU_TABLE_FREE.

This patch enables HAVE_RCU_TABLE_FREE and incorporates it into the
existing ARM TLB logic.

Signed-off-by: Steve Capper <steve.capper@linaro.org>
---
 arch/arm/Kconfig           |  1 +
 arch/arm/include/asm/tlb.h | 38 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c1f1a7e..e4a0e59 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -55,6 +55,7 @@ config ARM
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
+	select HAVE_RCU_TABLE_FREE if SMP
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index 0baf7f0..8cb5552 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -35,12 +35,39 @@
 
 #define MMU_GATHER_BUNDLE	8
 
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+static inline void __tlb_remove_table(void *_table)
+{
+	free_page_and_swap_cache((struct page *)_table);
+}
+
+struct mmu_table_batch {
+	struct rcu_head		rcu;
+	unsigned int		nr;
+	void			*tables[0];
+};
+
+#define MAX_TABLE_BATCH		\
+	((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
+
+extern void tlb_table_flush(struct mmu_gather *tlb);
+extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+
+#define tlb_remove_entry(tlb,entry)	tlb_remove_table(tlb,entry)
+#else
+#define tlb_remove_entry(tlb,entry)	tlb_remove_page(tlb,entry)
+#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
+
 /*
  * TLB handling.  This allows us to remove pages from the page
  * tables, and efficiently handle the TLB issues.
  */
 struct mmu_gather {
 	struct mm_struct	*mm;
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	struct mmu_table_batch	*batch;
+	unsigned int		need_flush;
+#endif
 	unsigned int		fullmm;
 	struct vm_area_struct	*vma;
 	unsigned long		start, end;
@@ -101,6 +128,9 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
 	tlb_flush(tlb);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	tlb_table_flush(tlb);
+#endif
 	free_pages_and_swap_cache(tlb->pages, tlb->nr);
 	tlb->nr = 0;
 	if (tlb->pages == tlb->local)
@@ -119,6 +149,10 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start
 	tlb->pages = tlb->local;
 	tlb->nr = 0;
 	__tlb_alloc_page(tlb);
+
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	tlb->batch = NULL;
+#endif
 }
 
 static inline void
@@ -195,7 +229,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 	tlb_add_flush(tlb, addr + SZ_1M);
 #endif
 
-	tlb_remove_page(tlb, pte);
+	tlb_remove_entry(tlb, pte);
 }
 
 static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
@@ -203,7 +237,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 {
 #ifdef CONFIG_ARM_LPAE
 	tlb_add_flush(tlb, addr);
-	tlb_remove_page(tlb, virt_to_page(pmdp));
+	tlb_remove_entry(tlb, virt_to_page(pmdp));
 #endif
 }
 
-- 
1.8.1.4

^ permalink raw reply related

* [RFC PATCH V2 2/4] arm: mm: implement get_user_pages_fast
From: Steve Capper @ 2014-02-06 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391703531-12845-1-git-send-email-steve.capper@linaro.org>

An implementation of get_user_pages_fast for ARM. It is based loosely
on the PowerPC implementation. We disable interrupts in the walker to
prevent the call_rcu_sched pagetable freeing code from running under
us.

We also explicitly fire an IPI in the Transparent HugePage splitting
case to prevent splits from interfering with the fast_gup walker.
As THP splits are relatively rare, this should not have a noticable
overhead.

Signed-off-by: Steve Capper <steve.capper@linaro.org>
---
 arch/arm/include/asm/pgtable-3level.h |   6 +
 arch/arm/mm/Makefile                  |   2 +-
 arch/arm/mm/gup.c                     | 251 ++++++++++++++++++++++++++++++++++
 3 files changed, 258 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mm/gup.c

diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 4f95039..4392c40 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -214,6 +214,12 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define pmd_trans_huge(pmd)	(pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
 #define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
+
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+			  pmd_t *pmdp);
+#endif
 #endif
 
 #define PMD_BIT_FUNC(fn,op) \
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index ecfe6e5..45cc6d8 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -6,7 +6,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   iomap.o
 
 obj-$(CONFIG_MMU)		+= fault-armv.o flush.o idmap.o ioremap.o \
-				   mmap.o pgd.o mmu.o
+				   mmap.o pgd.o mmu.o gup.o
 
 ifneq ($(CONFIG_MMU),y)
 obj-y				+= nommu.o
diff --git a/arch/arm/mm/gup.c b/arch/arm/mm/gup.c
new file mode 100644
index 0000000..2dcacad
--- /dev/null
+++ b/arch/arm/mm/gup.c
@@ -0,0 +1,251 @@
+/*
+ * arch/arm/mm/gup.c
+ *
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * Based on arch/powerpc/mm/gup.c which is:
+ * Copyright (C) 2008 Nick Piggin
+ * Copyright (C) 2008 Novell Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/rwsem.h>
+#include <linux/hugetlb.h>
+#include <asm/pgtable.h>
+
+static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
+			 int write, struct page **pages, int *nr)
+{
+	pte_t *ptep, *ptem;
+	int ret = 0;
+
+	ptem = ptep = pte_offset_map(&pmd, addr);
+	do {
+		pte_t pte = ACCESS_ONCE(*ptep);
+		struct page *page;
+
+		if (!pte_present_user(pte) || (write && !pte_write(pte)))
+			goto pte_unmap;
+
+		VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+		page = pte_page(pte);
+
+		if (!page_cache_get_speculative(page))
+			goto pte_unmap;
+
+		if (unlikely(pte_val(pte) != pte_val(*ptep))) {
+			put_page(page);
+			goto pte_unmap;
+		}
+
+		pages[*nr] = page;
+		(*nr)++;
+
+	} while (ptep++, addr += PAGE_SIZE, addr != end);
+
+	ret = 1;
+
+pte_unmap:
+	pte_unmap(ptem);
+	return ret;
+}
+
+static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
+		unsigned long end, int write, struct page **pages, int *nr)
+{
+	struct page *head, *page, *tail;
+	int refs;
+
+	if (!pmd_present(orig) || (write && !pmd_write(orig)))
+		return 0;
+
+	refs = 0;
+	head = pmd_page(orig);
+	page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+	tail = page;
+	do {
+		VM_BUG_ON(compound_head(page) != head);
+		pages[*nr] = page;
+		(*nr)++;
+		page++;
+		refs++;
+	} while (addr += PAGE_SIZE, addr != end);
+
+	if (!page_cache_add_speculative(head, refs)) {
+		*nr -= refs;
+		return 0;
+	}
+
+	if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
+		*nr -= refs;
+		while (refs--)
+			put_page(head);
+		return 0;
+	}
+
+	/*
+	 * Any tail pages need their mapcount reference taken before we
+	 * return. (This allows the THP code to bump their ref count when
+	 * they are split into base pages).
+	 */
+	while (refs--) {
+		if (PageTail(tail))
+			get_huge_page_tail(tail);
+		tail++;
+	}
+
+	return 1;
+}
+
+static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
+		int write, struct page **pages, int *nr)
+{
+	unsigned long next;
+	pmd_t *pmdp;
+
+	pmdp = pmd_offset(&pud, addr);
+	do {
+		pmd_t pmd = ACCESS_ONCE(*pmdp);
+		next = pmd_addr_end(addr, end);
+		if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+			return 0;
+
+		if (unlikely(pmd_thp_or_huge(pmd))) {
+			if (!gup_huge_pmd(pmd, pmdp, addr, next, write,
+				pages, nr))
+				return 0;
+		} else {
+			if (!gup_pte_range(pmd, addr, next, write, pages, nr))
+				return 0;
+		}
+	} while (pmdp++, addr = next, addr != end);
+
+	return 1;
+}
+
+static int gup_pud_range(pgd_t *pgdp, unsigned long addr, unsigned long end,
+		int write, struct page **pages, int *nr)
+{
+	unsigned long next;
+	pud_t *pudp;
+
+	pudp = pud_offset(pgdp, addr);
+	do {
+		pud_t pud = ACCESS_ONCE(*pudp);
+		next = pud_addr_end(addr, end);
+		if (pud_none(pud))
+			return 0;
+		else if (!gup_pmd_range(pud, addr, next, write, pages, nr))
+			return 0;
+	} while (pudp++, addr = next, addr != end);
+
+	return 1;
+}
+
+/*
+ * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
+ * back to the regular GUP.
+ */
+int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
+			  struct page **pages)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr, len, end;
+	unsigned long next, flags;
+	pgd_t *pgdp;
+	int nr = 0;
+
+	start &= PAGE_MASK;
+	addr = start;
+	len = (unsigned long) nr_pages << PAGE_SHIFT;
+	end = start + len;
+
+	if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
+					start, len)))
+		return 0;
+
+	/*
+	 * Disable interrupts, we use the nested form as we can already
+	 * have interrupts disabled by get_futex_key.
+	 *
+	 * With interrupts disabled, we block page table pages from being
+	 * freed from under us. See mmu_gather_tlb in asm-generic/tlb.h
+	 * for more details.
+	 */
+
+	local_irq_save(flags);
+	pgdp = pgd_offset(mm, addr);
+	do {
+		next = pgd_addr_end(addr, end);
+		if (pgd_none(*pgdp))
+			break;
+		else if (!gup_pud_range(pgdp, addr, next, write, pages, &nr))
+			break;
+	} while (pgdp++, addr = next, addr != end);
+	local_irq_restore(flags);
+
+	return nr;
+}
+
+int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+			struct page **pages)
+{
+	struct mm_struct *mm = current->mm;
+	int nr, ret;
+
+	start &= PAGE_MASK;
+	nr = __get_user_pages_fast(start, nr_pages, write, pages);
+	ret = nr;
+
+	if (nr < nr_pages) {
+		/* Try to get the remaining pages with get_user_pages */
+		start += nr << PAGE_SHIFT;
+		pages += nr;
+
+		down_read(&mm->mmap_sem);
+		ret = get_user_pages(current, mm, start,
+				     nr_pages - nr, write, 0, pages, NULL);
+		up_read(&mm->mmap_sem);
+
+		/* Have to be a bit careful with return values */
+		if (nr > 0) {
+			if (ret < 0)
+				ret = nr;
+			else
+				ret += nr;
+		}
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+static void thp_splitting_flush_sync(void *arg)
+{
+}
+
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+			  pmd_t *pmdp)
+{
+	pmd_t pmd = pmd_mksplitting(*pmdp);
+	VM_BUG_ON(address & ~PMD_MASK);
+	set_pmd_at(vma->vm_mm, address, pmdp, pmd);
+
+	/* dummy IPI to serialise against fast_gup */
+	smp_call_function(thp_splitting_flush_sync, NULL, 1);
+}
+#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-- 
1.8.1.4

^ permalink raw reply related

* [RFC PATCH V2 3/4] arm64: mm: Enable HAVE_RCU_TABLE_FREE logic
From: Steve Capper @ 2014-02-06 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391703531-12845-1-git-send-email-steve.capper@linaro.org>

In order to implement fast_get_user_pages we need to ensure that the
page table walker is protected from page table pages being freed from
under it.

This patch enables HAVE_RCU_TABLE_FREE and incorporates it into the
existing arm64 TLB logic. Any page table pages belonging to address
spaces with multiple users will be call_rcu_sched freed. Meaning
that disabling interrupts will block the free and protect the fast
gup page walker.

Signed-off-by: Steve Capper <steve.capper@linaro.org>
---
 arch/arm64/Kconfig           |  1 +
 arch/arm64/include/asm/tlb.h | 27 +++++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6d4dd22..129bd6a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -28,6 +28,7 @@ config ARM64
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS
 	select HAVE_MEMBLOCK
 	select HAVE_PERF_EVENTS
+	select HAVE_RCU_TABLE_FREE
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 717031a..8999823 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -27,12 +27,33 @@
 
 #define MMU_GATHER_BUNDLE	8
 
+static inline void __tlb_remove_table(void *_table)
+{
+	free_page_and_swap_cache((struct page *)_table);
+}
+
+struct mmu_table_batch {
+	struct rcu_head		rcu;
+	unsigned int		nr;
+	void			*tables[0];
+};
+
+#define MAX_TABLE_BATCH		\
+	((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
+
+extern void tlb_table_flush(struct mmu_gather *tlb);
+extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+
+#define tlb_remove_entry(tlb,entry)	tlb_remove_table(tlb,entry)
+
 /*
  * TLB handling.  This allows us to remove pages from the page
  * tables, and efficiently handle the TLB issues.
  */
 struct mmu_gather {
 	struct mm_struct	*mm;
+	struct mmu_table_batch	*batch;
+	unsigned int		need_flush;
 	unsigned int		fullmm;
 	struct vm_area_struct	*vma;
 	unsigned long		start, end;
@@ -91,6 +112,7 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
 	tlb_flush(tlb);
+	tlb_table_flush(tlb);
 	free_pages_and_swap_cache(tlb->pages, tlb->nr);
 	tlb->nr = 0;
 	if (tlb->pages == tlb->local)
@@ -109,6 +131,7 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start
 	tlb->pages = tlb->local;
 	tlb->nr = 0;
 	__tlb_alloc_page(tlb);
+	tlb->batch = NULL;
 }
 
 static inline void
@@ -172,7 +195,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 {
 	pgtable_page_dtor(pte);
 	tlb_add_flush(tlb, addr);
-	tlb_remove_page(tlb, pte);
+	tlb_remove_entry(tlb, pte);
 }
 
 #ifndef CONFIG_ARM64_64K_PAGES
@@ -180,7 +203,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 				  unsigned long addr)
 {
 	tlb_add_flush(tlb, addr);
-	tlb_remove_page(tlb, virt_to_page(pmdp));
+	tlb_remove_entry(tlb, virt_to_page(pmdp));
 }
 #endif
 
-- 
1.8.1.4

^ permalink raw reply related

* [RFC PATCH V2 4/4] arm64: mm: implement get_user_pages_fast
From: Steve Capper @ 2014-02-06 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391703531-12845-1-git-send-email-steve.capper@linaro.org>

An implementation of get_user_pages_fast for arm64. It is based on the
arm implementation (it has the added ability to walk huge puds) which
is loosely on the PowerPC implementation. We disable interrupts in the
walker to prevent the call_rcu_sched pagetable freeing code from
running under us.

We also explicitly fire an IPI in the Transparent HugePage splitting
case to prevent splits from interfering with the fast_gup walker.
As THP splits are relatively rare, this should not have a noticable
overhead.

Signed-off-by: Steve Capper <steve.capper@linaro.org>
---
 arch/arm64/include/asm/pgtable.h |   4 +
 arch/arm64/mm/Makefile           |   2 +-
 arch/arm64/mm/gup.c              | 297 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 302 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/mm/gup.c

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7f2b60a..8cfa1aa 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -212,6 +212,10 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define pmd_trans_huge(pmd)	(pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
 #define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
+#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+struct vm_area_struct;
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+			  pmd_t *pmdp);
 #endif
 
 #define PMD_BIT_FUNC(fn,op) \
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index b51d364..44b2148 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -1,5 +1,5 @@
 obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   cache.o copypage.o flush.o \
 				   ioremap.o mmap.o pgd.o mmu.o \
-				   context.o tlb.o proc.o
+				   context.o tlb.o proc.o gup.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
diff --git a/arch/arm64/mm/gup.c b/arch/arm64/mm/gup.c
new file mode 100644
index 0000000..45dd908
--- /dev/null
+++ b/arch/arm64/mm/gup.c
@@ -0,0 +1,297 @@
+/*
+ * arch/arm64/mm/gup.c
+ *
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * Based on arch/powerpc/mm/gup.c which is:
+ * Copyright (C) 2008 Nick Piggin
+ * Copyright (C) 2008 Novell Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/rwsem.h>
+#include <linux/hugetlb.h>
+#include <asm/pgtable.h>
+
+static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
+			 int write, struct page **pages, int *nr)
+{
+	pte_t *ptep, *ptem;
+	int ret = 0;
+
+	ptem = ptep = pte_offset_map(&pmd, addr);
+	do {
+		pte_t pte = ACCESS_ONCE(*ptep);
+		struct page *page;
+
+		if (!pte_valid_user(pte) || (write && !pte_write(pte)))
+			goto pte_unmap;
+
+		VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+		page = pte_page(pte);
+
+		if (!page_cache_get_speculative(page))
+			goto pte_unmap;
+
+		if (unlikely(pte_val(pte) != pte_val(*ptep))) {
+			put_page(page);
+			goto pte_unmap;
+		}
+
+		pages[*nr] = page;
+		(*nr)++;
+
+	} while (ptep++, addr += PAGE_SIZE, addr != end);
+
+	ret = 1;
+
+pte_unmap:
+	pte_unmap(ptem);
+	return ret;
+}
+
+static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
+		unsigned long end, int write, struct page **pages, int *nr)
+{
+	struct page *head, *page, *tail;
+	int refs;
+
+	if (!pmd_present(orig) || (write && !pmd_write(orig)))
+		return 0;
+
+	refs = 0;
+	head = pmd_page(orig);
+	page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+	tail = page;
+	do {
+		VM_BUG_ON(compound_head(page) != head);
+		pages[*nr] = page;
+		(*nr)++;
+		page++;
+		refs++;
+	} while (addr += PAGE_SIZE, addr != end);
+
+	if (!page_cache_add_speculative(head, refs)) {
+		*nr -= refs;
+		return 0;
+	}
+
+	if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
+		*nr -= refs;
+		while (refs--)
+			put_page(head);
+		return 0;
+	}
+
+	/*
+	 * Any tail pages need their mapcount reference taken before we
+	 * return. (This allows the THP code to bump their ref count when
+	 * they are split into base pages).
+	 */
+	while (refs--) {
+		if (PageTail(tail))
+			get_huge_page_tail(tail);
+		tail++;
+	}
+
+	return 1;
+}
+
+static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr,
+		unsigned long end, int write, struct page **pages, int *nr)
+{
+	struct page *head, *page, *tail;
+	pmd_t origpmd = __pmd(pud_val(orig));
+	int refs;
+
+	if (!pmd_present(origpmd) || (write && !pmd_write(origpmd)))
+		return 0;
+
+	refs = 0;
+	head = pmd_page(origpmd);
+	page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
+	tail = page;
+	do {
+		VM_BUG_ON(compound_head(page) != head);
+		pages[*nr] = page;
+		(*nr)++;
+		page++;
+		refs++;
+	} while (addr += PAGE_SIZE, addr != end);
+
+	if (!page_cache_add_speculative(head, refs)) {
+		*nr -= refs;
+		return 0;
+	}
+
+	if (unlikely(pud_val(orig) != pud_val(*pudp))) {
+		*nr -= refs;
+		while (refs--)
+			put_page(head);
+		return 0;
+	}
+
+	while (refs--) {
+		if (PageTail(tail))
+			get_huge_page_tail(tail);
+		tail++;
+	}
+
+	return 1;
+}
+
+static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
+		int write, struct page **pages, int *nr)
+{
+	unsigned long next;
+	pmd_t *pmdp;
+
+	pmdp = pmd_offset(&pud, addr);
+	do {
+		pmd_t pmd = ACCESS_ONCE(*pmdp);
+		next = pmd_addr_end(addr, end);
+		if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+			return 0;
+
+		if (unlikely(pmd_huge(pmd) || pmd_trans_huge(pmd))) {
+			if (!gup_huge_pmd(pmd, pmdp, addr, next, write,
+					pages, nr))
+				return 0;
+		} else {
+			if (!gup_pte_range(pmd, addr, next, write, pages, nr))
+				return 0;
+		}
+	} while (pmdp++, addr = next, addr != end);
+
+	return 1;
+}
+
+static int gup_pud_range(pgd_t *pgdp, unsigned long addr, unsigned long end,
+		int write, struct page **pages, int *nr)
+{
+	unsigned long next;
+	pud_t *pudp;
+
+	pudp = pud_offset(pgdp, addr);
+	do {
+		pud_t pud = ACCESS_ONCE(*pudp);
+		next = pud_addr_end(addr, end);
+		if (pud_none(pud))
+			return 0;
+		if (pud_huge(pud)) {
+			if (!gup_huge_pud(pud, pudp, addr, next, write,
+					pages, nr))
+				return 0;
+		}
+		else if (!gup_pmd_range(pud, addr, next, write, pages, nr))
+			return 0;
+	} while (pudp++, addr = next, addr != end);
+
+	return 1;
+}
+
+/*
+ * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
+ * back to the regular GUP.
+ */
+int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
+			  struct page **pages)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr, len, end;
+	unsigned long next, flags;
+	pgd_t *pgdp;
+	int nr = 0;
+
+	start &= PAGE_MASK;
+	addr = start;
+	len = (unsigned long) nr_pages << PAGE_SHIFT;
+	end = start + len;
+
+	if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
+					start, len)))
+		return 0;
+
+	/*
+	 * Disable interrupts, we use the nested form as we can already
+	 * have interrupts disabled by get_futex_key.
+	 *
+	 * With interrupts disabled, we block page table pages from being
+	 * freed from under us. See mmu_gather_tlb in asm-generic/tlb.h
+	 * for more details.
+	 */
+
+	local_irq_save(flags);
+	pgdp = pgd_offset(mm, addr);
+	do {
+		next = pgd_addr_end(addr, end);
+		if (pgd_none(*pgdp))
+			break;
+		else if (!gup_pud_range(pgdp, addr, next, write, pages, &nr))
+			break;
+	} while (pgdp++, addr = next, addr != end);
+	local_irq_restore(flags);
+
+	return nr;
+}
+
+int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+			struct page **pages)
+{
+	struct mm_struct *mm = current->mm;
+	int nr, ret;
+
+	start &= PAGE_MASK;
+	nr = __get_user_pages_fast(start, nr_pages, write, pages);
+	ret = nr;
+
+	if (nr < nr_pages) {
+		/* Try to get the remaining pages with get_user_pages */
+		start += nr << PAGE_SHIFT;
+		pages += nr;
+
+		down_read(&mm->mmap_sem);
+		ret = get_user_pages(current, mm, start,
+				     nr_pages - nr, write, 0, pages, NULL);
+		up_read(&mm->mmap_sem);
+
+		/* Have to be a bit careful with return values */
+		if (nr > 0) {
+			if (ret < 0)
+				ret = nr;
+			else
+				ret += nr;
+		}
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static void thp_splitting_flush_sync(void *arg)
+{
+}
+
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+			  pmd_t *pmdp)
+{
+	pmd_t pmd = pmd_mksplitting(*pmdp);
+	VM_BUG_ON(address & ~PMD_MASK);
+	set_pmd_at(vma->vm_mm, address, pmdp, pmd);
+
+	/* dummy IPI to serialise against fast_gup */
+	smp_call_function(thp_splitting_flush_sync, NULL, 1);
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH] backlight: add PWM dependencies
From: Arnd Bergmann @ 2014-02-06 16:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201402061708.05845.arnd@arndb.de>

On Thursday 06 February 2014 17:08:05 Arnd Bergmann wrote:
> 
> Finally, I have recently encountered a couple of drivers
> (BACKLIGHT_LM3630A, BACKLIGHT_LP855X, BACKLIGHT_LP8788) that use
> the PWM interfaces but are missing a 'depends on PWM'. This is
> strictly speaking a different problem, but we could try to solve
> it at the same time.
> 

D'oh. I just realized this is the bug that started the thread
with Linus' patch. Apparently I found one more instance that
he didn't find though.

	Arnd

^ permalink raw reply

* [PATCH 4/4] ARM: Kirkwood: Add support for many Synology NAS devices
From: Arnd Bergmann @ 2014-02-06 16:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140206160126.GH29860@lunn.ch>

On Thursday 06 February 2014 17:01:26 Andrew Lunn wrote:

> , but this is, imho,
> > over-fragmenting.  I'm sure there's a reason you chose this path, but
> > you haven't explained why in your commit log. So I'm left guessing...
> 
> Synology seem to build there devices like lego. They have two
> different RTC blocks. They have three different fan alarm blocks, four
> different led blocks, etc. And to build a product, the just select a
> group of blocks and put them together.

I guess the Armada-370 and newer based ds213j and dsx14 will also be
able to reuse some of the blocks, right?

	Arnd

^ permalink raw reply

* [PATCH 4/4] ARM: Kirkwood: Add support for many Synology NAS devices
From: Ian Campbell @ 2014-02-06 16:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140206153939.GD8533@titan.lakedaemon.net>

On Thu, 2014-02-06 at 10:39 -0500, Jason Cooper wrote:
> 
> > +                     pmx_fan_33: pmx-fan-33 {
> > +                             marvell,pins = "mpp33";
> > +                             marvell,function = "gpo";
> > +                     }; 

Typo I think.

Ian.

^ permalink raw reply

* [RFC] dt-bindings: configuration of parent clocks and clock frequency
From: Mike Turquette @ 2014-02-06 16:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F0DA07.6050903@samsung.com>

Quoting Marek Szyprowski (2014-02-04 04:16:07)
> Hello,
> 
> On 2014-02-01 04:06, Mike Turquette wrote:
> > Quoting Sylwester Nawrocki (2014-01-21 04:48:43)
> > > 5. Similarly to the regulator bindings the clock names could be appended
> > >   to name of a DT property:
> > >
> > >  [clk_name]-assigned-clock-parent = <...>;
> > >  [clk_name]-assigned-clock-rate = <...>;
> >
> > I have always been partial to the way that the reg framework does its
> > [reg_name]-supply. We could shorten it to something like:
> >
> > [clk-name]-asn-parent = ....
> > [clk-name]-asn-rate = ...
> >
> > This is actually the format that was discussed at the ARM kernel summit
> > IIRC.
> 
> I think that "[clk-name]-clk-parent" and "[clk-name]-clk-rate" will be a bit
> more descriptive names instead of quite ambiguous "asn".

+1

Regards,
Mike

> 
> Best regards
> -- 
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
> 

^ permalink raw reply

* [PATCH v2 6/6] cpu/idle.c: move to sched/idle.c
From: Peter Zijlstra @ 2014-02-06 16:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.11.1402061152550.1906@knanqh.ubzr>

On Thu, Feb 06, 2014 at 02:09:59PM +0000, Nicolas Pitre wrote:
> Hi Peter,
> 
> Did you merge those patches in your tree? 

tree, tree, what's in a word. Its in my patch stack yes. I should get
some of that into tip I suppose, been side-tracked a bit this week.
Sorry for the delay.

> If so, is it published somewhere?  

http://programming.kicks-ass.net/sekrit/patches.tar.bz2

It is of varying quality at best.

> That would be a good idea if that could appear in linux-next 
> so to prevent people from adding more calls to cpuidle_idle_call() from 
> architecture code.  I'm sending you 2 additional patches right away to 
> remove those that appeared in v3.14-rc1.

Yeah, once they land in tip they'll end up in -next automagically. I'll
try and get that sorted tomorrow somewhere.

^ permalink raw reply

* [PATCH v3 3/6] misc: fuse: Add efuse driver for Tegra
From: Stephen Warren @ 2014-02-06 16:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140206091114.GK19389@tbergstrom-lnx.Nvidia.com>

On 02/06/2014 02:11 AM, Peter De Schrijver wrote:
> On Wed, Feb 05, 2014 at 08:15:46PM +0100, Stephen Warren wrote:
>> On 01/28/2014 04:36 PM, Peter De Schrijver wrote:
>>> Implement fuse driver for Tegra20, Tegra30, Tegra114 and Tegra124.

>>> diff --git a/Documentation/ABI/testing/sysfs-driver-tegra-fuse b/Documentation/ABI/testing/sysfs-driver-tegra-fuse
>>> +What:		/sys/devices/*/<our-device>/fuse
>>> +Date:		December 2013
>>> +Contact:	Peter De Schrijver <pdeschrijver@nvidia.com>
>>> +Description:	read-only access to the efuses on Tegra20, Tegra30, Tegra114
>>> +		and Tegra124 SoC's from NVIDIA. The efuses contain write once
>>> +		data programmed at the factory.
>>> +Users:		any user space application which wants to read the efuses on
>>> +		Tegra SoC's
>>
>> Surely this file should describe the format of the file, since that's
>> part of the ABI too, right?
>>
> 
> Part of the fuse data is ODM defined so possibly board specific.

I didn't mean the interpretation of which fuses mean what semantically,
but rather the data format of the file. IIRC looking at the code, it's
just a binary dump of the fuses, but it might be worth spelling out that
it's a byte-oriented binary file, with fuse 0 in bit 0 of byte 0 etc.?

^ permalink raw reply

* [PATCH 1/4] ARM: STi: add stid127 soc support
From: Arnd Bergmann @ 2014-02-06 16:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F22508.7080706@st.com>

On Wednesday 05 February 2014, srinivas kandagatla wrote:
> Currently l2cc bindings has few optional properties like.
> 
> - arm,data-latency
> - arm,tag-latency
> - arm,dirty-latency
> - arm,filter-ranges
> - interrupts :
> - cache-id-part:
> - wt-override:
> 
> These does not include properties to set "way-size", "associativity",
> "enabling prefetching", "Prefetch drop enable", "prefetch offset",
> "Double linefill" and few more in prefect control register and
> aux-control register.
> 
> This is not just a issue with STi SOCs, having a quick look, I can see
> that few more SOCs have similar requirements to set these properties.
> 
> We could do two things to get l2 setup automatically on STi SOCS.
> 
> 1> Either define these properties case-by-case basic, which might be
> useful for other SOCs too.
> 
> 2> Or Add new compatible string for STi SoCs so that they can
> automatically setup these values in cache-l2x0.c
> 
> Am Ok with either approaches.
> 

I suggested 1 in the past, but the objection that I saw (can't
find the email at the moment) was that the additional settings
are "configuration" rather than "hardware properties". What I'd
really need to know from you is which of properties you listed
as missing above are actually needed for your platform, and whether
they can be classified as hardware specific or just configuration.

	Arnd

^ permalink raw reply

* [PATCH 1/2] PPC: powernv: remove redundant cpuidle_idle_call()
From: Preeti U Murthy @ 2014-02-06 16:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKnoXLxCAqKaniGOwegNcOarS4FpoNKDY5PxOhe6j4wdtUAkLQ@mail.gmail.com>

Hi Daniel,

On 02/06/2014 09:55 PM, Daniel Lezcano wrote:
> Hi Nico,
> 
> 
> On 6 February 2014 14:16, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> 
>> The core idle loop now takes care of it.
>>
>> Signed-off-by: Nicolas Pitre <nico@linaro.org>
>> ---
>>  arch/powerpc/platforms/powernv/setup.c | 13 +------------
>>  1 file changed, 1 insertion(+), 12 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/powernv/setup.c
>> b/arch/powerpc/platforms/powernv/setup.c
>> index 21166f65c9..a932feb290 100644
>> --- a/arch/powerpc/platforms/powernv/setup.c
>> +++ b/arch/powerpc/platforms/powernv/setup.c
>> @@ -26,7 +26,6 @@
>>  #include <linux/of_fdt.h>
>>  #include <linux/interrupt.h>
>>  #include <linux/bug.h>
>> -#include <linux/cpuidle.h>
>>
>>  #include <asm/machdep.h>
>>  #include <asm/firmware.h>
>> @@ -217,16 +216,6 @@ static int __init pnv_probe(void)
>>         return 1;
>>  }
>>
>> -void powernv_idle(void)
>> -{
>> -       /* Hook to cpuidle framework if available, else
>> -        * call on default platform idle code
>> -        */
>> -       if (cpuidle_idle_call()) {
>> -               power7_idle();
>> -       }
>>
> 
> The cpuidle_idle_call is called from arch_cpu_idle in
> arch/powerpc/kernel/idle.c between a ppc64_runlatch_off|on section.
> Shouldn't the cpuidle-powernv driver call these functions when entering
> idle ?

Yes they should, I will send out a patch that does that ontop of this.
There have been cpuidle driver cleanups for powernv and pseries in this
merge window. While no change would be required in the pseries cpuidle
driver as a result of Nicolas's cleanup, we would need to add the
ppc64_runlatch_on and off functions before and after the entry into the
powernv idle states.

Thanks

Regards
Preeti U Murthy
> 
>   -- Daniel
> 
> 
>> -}
>> -
>>  define_machine(powernv) {
>>         .name                   = "PowerNV",
>>         .probe                  = pnv_probe,
>> @@ -236,7 +225,7 @@ define_machine(powernv) {
>>         .show_cpuinfo           = pnv_show_cpuinfo,
>>         .progress               = pnv_progress,
>>         .machine_shutdown       = pnv_shutdown,
>> -       .power_save             = powernv_idle,
>> +       .power_save             = power7_idle,
>>         .calibrate_decr         = generic_calibrate_decr,
>>  #ifdef CONFIG_KEXEC
>>         .kexec_cpu_down         = pnv_kexec_cpu_down,
>> --
>> 1.8.4.108.g55ea5f6
>>
>>
> 

^ permalink raw reply

* [PATCH 4/4] ARM: Kirkwood: Add support for many Synology NAS devices
From: Andrew Lunn @ 2014-02-06 16:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391704765.2162.7.camel@kazak.uk.xensource.com>

On Thu, Feb 06, 2014 at 04:39:25PM +0000, Ian Campbell wrote:
> On Thu, 2014-02-06 at 10:39 -0500, Jason Cooper wrote:
> > 
> > > +                     pmx_fan_33: pmx-fan-33 {
> > > +                             marvell,pins = "mpp33";
> > > +                             marvell,function = "gpo";
> > > +                     }; 
> 
> Typo I think.

Hi Ian

drivers/pinctrl/mvebu/pinctrl-kirkwood.c:

        MPP_MODE(33,
                MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(0, 1, 1, 1, 1, 0)),
                MPP_VAR_FUNCTION(0x2, "tdm", "dtx",      V(0, 0, 1, 1, 1, 0)),
                MPP_VAR_FUNCTION(0x3, "ge1", "txctl",    V(0, 1, 1, 1, 1, 0)),
                MPP_VAR_FUNCTION(0xb, "lcd", "d13",      V(0, 0, 0, 0, 1, 0))),
        MPP_MODE(34,

It is output only.

I actually had the opposite bug in v1, setup two gpo's as gpio's.

  Andrew

^ permalink raw reply

* [PATCH 4/4] ARM: Kirkwood: Add support for many Synology NAS devices
From: Ian Campbell @ 2014-02-06 16:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140206165003.GJ29860@lunn.ch>

On Thu, 2014-02-06 at 17:50 +0100, Andrew Lunn wrote:
> On Thu, Feb 06, 2014 at 04:39:25PM +0000, Ian Campbell wrote:
> > On Thu, 2014-02-06 at 10:39 -0500, Jason Cooper wrote:
> > > 
> > > > +                     pmx_fan_33: pmx-fan-33 {
> > > > +                             marvell,pins = "mpp33";
> > > > +                             marvell,function = "gpo";
> > > > +                     }; 
> > 
> > Typo I think.
> 
> Hi Ian
> 
> drivers/pinctrl/mvebu/pinctrl-kirkwood.c:
> 
>         MPP_MODE(33,
>                 MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(0, 1, 1, 1, 1, 0)),
>                 MPP_VAR_FUNCTION(0x2, "tdm", "dtx",      V(0, 0, 1, 1, 1, 0)),
>                 MPP_VAR_FUNCTION(0x3, "ge1", "txctl",    V(0, 1, 1, 1, 1, 0)),
>                 MPP_VAR_FUNCTION(0xb, "lcd", "d13",      V(0, 0, 0, 0, 1, 0))),
>         MPP_MODE(34,
> 
> It is output only.

Oops, Sorry for the noise!

> 
> I actually had the opposite bug in v1, setup two gpo's as gpio's.
> 
>   Andrew
> 

^ permalink raw reply


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