Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 3/7] net: phy: broadcom: Add BCM54810 PHY entry
From: Jon Mason @ 2016-11-04  5:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>

The BCM54810 PHY requires some semi-unique configuration, which results
in some additional configuration in addition to the standard config.
Also, some users of the BCM54810 require the PHY lanes to be swapped.
Since there is no way to detect this, add a device tree query to see if
it is applicable.

Inspired-by: Vikas Soni <vsoni@broadcom.com>
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/Kconfig    |  2 +-
 drivers/net/phy/broadcom.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/brcmphy.h    |  9 +++++++
 3 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index ff31c10..d3fcfd2 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -217,7 +217,7 @@ config BROADCOM_PHY
 	select BCM_NET_PHYLIB
 	---help---
 	  Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
-	  BCM5481 and BCM5482 PHYs.
+	  BCM5481, BCM54810 and BCM5482 PHYs.
 
 config CICADA_PHY
 	tristate "Cicada PHYs"
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 3a64b3d..b1e32e9 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 #include <linux/phy.h>
 #include <linux/brcmphy.h>
-
+#include <linux/of.h>
 
 #define BRCM_PHY_MODEL(phydev) \
 	((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
@@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
 	return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
 }
 
+static int bcm54810_config(struct phy_device *phydev)
+{
+	int rc, val;
+
+	val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
+	val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
+	rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
+			       val);
+	if (rc < 0)
+		return rc;
+
+	val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
+	val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
+	val |= MII_BCM54XX_AUXCTL_MISC_WREN;
+	rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
+				  val);
+	if (rc < 0)
+		return rc;
+
+	val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
+	val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
+	rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
 static int bcm50610_a0_workaround(struct phy_device *phydev)
 {
@@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev)
 	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
 		bcm54xx_adjust_rxrefclk(phydev);
 
+	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
+		err = bcm54810_config(phydev);
+		if (err)
+			return err;
+	}
+
 	bcm54xx_phydsp_config(phydev);
 
 	return 0;
@@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev)
 
 static int bcm5481_config_aneg(struct phy_device *phydev)
 {
+	struct device_node *np = phydev->mdio.dev.of_node;
 	int ret;
 
 	/* Aneg firsly. */
@@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
 		phy_write(phydev, 0x18, reg);
 	}
 
+	if (of_property_read_bool(np, "enet-phy-lane-swap")) {
+		/* Lane Swap - Undocumented register...magic! */
+		ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
+					0x11B);
+		if (ret < 0)
+			return ret;
+	}
+
 	return ret;
 }
 
@@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = {
 	.ack_interrupt	= bcm_phy_ack_intr,
 	.config_intr	= bcm_phy_config_intr,
 }, {
+	.phy_id         = PHY_ID_BCM54810,
+	.phy_id_mask    = 0xfffffff0,
+	.name           = "Broadcom BCM54810",
+	.features       = PHY_GBIT_FEATURES |
+			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+	.config_init    = bcm54xx_config_init,
+	.config_aneg    = bcm5481_config_aneg,
+	.read_status    = genphy_read_status,
+	.ack_interrupt  = bcm_phy_ack_intr,
+	.config_intr    = bcm_phy_config_intr,
+}, {
 	.phy_id		= PHY_ID_BCM5482,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5482",
@@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
 	{ PHY_ID_BCM54616S, 0xfffffff0 },
 	{ PHY_ID_BCM5464, 0xfffffff0 },
 	{ PHY_ID_BCM5481, 0xfffffff0 },
+	{ PHY_ID_BCM54810, 0xfffffff0 },
 	{ PHY_ID_BCM5482, 0xfffffff0 },
 	{ PHY_ID_BCM50610, 0xfffffff0 },
 	{ PHY_ID_BCM50610M, 0xfffffff0 },
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 0ed6691..848dc50 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -13,6 +13,7 @@
 #define PHY_ID_BCM5241			0x0143bc30
 #define PHY_ID_BCMAC131			0x0143bc70
 #define PHY_ID_BCM5481			0x0143bca0
+#define PHY_ID_BCM54810			0x03625d00
 #define PHY_ID_BCM5482			0x0143bcb0
 #define PHY_ID_BCM5411			0x00206070
 #define PHY_ID_BCM5421			0x002060e0
@@ -56,6 +57,7 @@
 #define PHY_BRCM_EXT_IBND_TX_ENABLE	0x00002000
 #define PHY_BRCM_CLEAR_RGMII_MODE	0x00004000
 #define PHY_BRCM_DIS_TXCRXC_NOENRGY	0x00008000
+
 /* Broadcom BCM7xxx specific workarounds */
 #define PHY_BRCM_7XXX_REV(x)		(((x) >> 8) & 0xff)
 #define PHY_BRCM_7XXX_PATCH(x)		((x) & 0xff)
@@ -111,6 +113,7 @@
 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC	0x7000
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC	0x0007
 #define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT	12
+#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN	(1 << 8)
 
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK	0x0007
 
@@ -192,6 +195,12 @@
 #define BCM5482_SSD_SGMII_SLAVE_EN	0x0002	/* Slave mode enable */
 #define BCM5482_SSD_SGMII_SLAVE_AD	0x0001	/* Slave auto-detection */
 
+/* BCM54810 Registers */
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL	(MII_BCM54XX_EXP_SEL_ER + 0x90)
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN	(1 << 0)
+#define BCM54810_SHD_CLK_CTL			0x3
+#define BCM54810_SHD_CLK_CTL_GTXCLK_EN		(1 << 9)
+
 
 /*****************************************************************************/
 /* Fast Ethernet Transceiver definitions. */
-- 
2.7.4

^ permalink raw reply related

* [PATCH v6 2/7] Documentation: devicetree: add PHY lane swap binding
From: Jon Mason @ 2016-11-04  5:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>

Add the documentation for PHY lane swapping.  This is a boolean entry to
notify the phy device drivers that the TX/RX lanes need to be swapped.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 Documentation/devicetree/bindings/net/phy.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
index bc1c3c8..4627da3 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -35,6 +35,10 @@ Optional Properties:
 - broken-turn-around: If set, indicates the PHY device does not correctly
   release the turn around line low at the end of a MDIO transaction.
 
+- enet-phy-lane-swap: If set, indicates the PHY will swap the TX/RX lanes to
+  compensate for the board being designed with the lanes swapped.
+
+
 Example:
 
 ethernet-phy at 0 {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v6 1/7] net: phy: broadcom: add bcm54xx_auxctl_read
From: Jon Mason @ 2016-11-04  5:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478236262-3351-1-git-send-email-jon.mason@broadcom.com>

Add a helper function to read the AUXCTL register for the BCM54xx.  This
mirrors the bcm54xx_auxctl_write function already present in the code.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/phy/broadcom.c | 10 ++++++++++
 include/linux/brcmphy.h    |  1 +
 2 files changed, 11 insertions(+)

diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 583ef8a..3a64b3d 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver");
 MODULE_AUTHOR("Maciej W. Rozycki");
 MODULE_LICENSE("GPL");
 
+static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
+{
+	/* The register must be written to both the Shadow Register Select and
+	 * the Shadow Read Register Selector
+	 */
+	phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum |
+		  regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
+	return phy_read(phydev, MII_BCM54XX_AUX_CTL);
+}
+
 static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
 {
 	return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 60def78..0ed6691 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -110,6 +110,7 @@
 #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX	0x0200
 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC	0x7000
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC	0x0007
+#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT	12
 
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK	0x0007
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v6 0/7] add NS2 support to bgmac
From: Jon Mason @ 2016-11-04  5:10 UTC (permalink / raw)
  To: linux-arm-kernel

Changes in v6:
* Use a common bgmac_phy_connect_direct (per Rafal Milecki) 
* Rebased on latest net-next
* Added Reviewed-by to the relevant patches


Changes in v5:
* Change a pr_err to netdev_err (per Scott Branden)
* Reword the lane swap binding documentation (per Andrew Lunn)


Changes in v4:
* Actually send out the lane swap binding doc patch (Per Scott Branden)
* Remove unused #define (Per Andrew Lunn)


Changes in v3:
* Clean-up the bgmac DT binding doc (per Rob Herring)
* Document the lane swap binding and make it generic (Per Andrew Lunn)


Changes in v2:
* Remove the PHY power-on (per Andrew Lunn)
* Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn)
  This results on none of the original PHY code from Vikas being
  present.  So, I'm removing him as an author and giving him
  "Inspired-by" credit.
* Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian
  Fainelli)
* Remove bgmac sleep (per Florian Fainelli)
* Re-add bgmac chip reset (per Florian Fainelli and Ray Jui)
* Rebased on latest net-next
* Added patch for bcm54xx_auxctl_read, which is used in the BCM54810


Jon Mason (7):
  net: phy: broadcom: add bcm54xx_auxctl_read
  Documentation: devicetree: add PHY lane swap binding
  net: phy: broadcom: Add BCM54810 PHY entry
  Documentation: devicetree: net: add NS2 bindings to amac
  net: ethernet: bgmac: device tree phy enablement
  net: ethernet: bgmac: add NS2 support
  arm64: dts: NS2: add AMAC ethernet support

 .../devicetree/bindings/net/brcm,amac.txt          | 16 +++--
 Documentation/devicetree/bindings/net/phy.txt      |  4 ++
 arch/arm64/boot/dts/broadcom/ns2-svk.dts           |  5 ++
 arch/arm64/boot/dts/broadcom/ns2.dtsi              | 12 ++++
 drivers/net/ethernet/broadcom/bgmac-bcma.c         | 22 +++++++
 drivers/net/ethernet/broadcom/bgmac-platform.c     | 74 +++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bgmac.c              | 32 +++-------
 drivers/net/ethernet/broadcom/bgmac.h              |  9 +++
 drivers/net/phy/Kconfig                            |  2 +-
 drivers/net/phy/broadcom.c                         | 68 +++++++++++++++++++-
 include/linux/brcmphy.h                            | 10 +++
 11 files changed, 222 insertions(+), 32 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [RESEND PATCH v1 05/11] dt-bindings: perf: hisi: Add Devicetree bindings for Hisilicon SoC PMU
From: Anurup M @ 2016-11-04  5:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103182609.GA11071@kozik-lap>



On Thursday 03 November 2016 11:56 PM, Krzysztof Kozlowski wrote:
> On Thu, Nov 03, 2016 at 01:42:01AM -0400, Anurup M wrote:
>> 	1) Device tree bindings for Hisilicon SoC PMU.
>> 	2) Add example for Hisilicon L3 cache, MN and DDRC PMU.
> Get rid of this weird indentation in all patches.
Thanks. I shall remove the TAB from the commit message in all patches.
>
>> Signed-off-by: Anurup M <anurup.m@huawei.com>
>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>> ---
>>   .../devicetree/bindings/arm/hisilicon/pmu.txt      | 127 +++++++++++++++++++++
>>   1 file changed, 127 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>>
>> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>> new file mode 100644
>> index 0000000..e7b35e0
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
>> @@ -0,0 +1,127 @@
>> +Hisilicon SoC hip05/06/07 ARMv8 PMU
>> +===================================
>> +
>> +The Hisilicon SoC chips like hip05/06/07 etc. consist of varous independent
>> +system device PMU's such as L3 cache (L3C), Miscellaneous Nodes(MN) and DDR
>> +comtroller. These PMU devices are independent and have hardware logic to
>> +gather statistics and performance information.
>> +
>> +HiSilicon SoC chip is encapsulated by multiple CPU and IO die's. The CPU die
>> +is called as Super CPU cluster (SCCL) which includes 16 cpu-cores. Every SCCL
>> +is further grouped as CPU clusters (CCL) which includes 4 cpu-cores each.
>> +e.g. In the case of hip05/06/07, each SCCL has 1 L3 cache and 1 MN PMU device.
>> +
>> +The Hisilicon SoC PMU DT node bindigs for uncore PMU devices are as below.
>> +For PMU devices like L3 cache. MN etc. which are accessed using the djtag,
>> +the parent node will be the djtag node of the corresponding CPU die(SCCL).
>> +
>> +For uncore PMU devices there are some common required properties as detailed
>> +below.
>> +
>> +Required properties:
>> +	- compatible : This field contain two values. The first value is
>> +		always "hisilicon" and second value is the Module type as shown
>> +		in below examples:
> Over-complicated sentence. Just:
>
> 	- compatible : One of:
> 		"hisilicon,hisi-pmu-l3c-v1" for Hisilicon SoC L3C PMU
> 			device (Version 1)
> 		...
> 		...
Thanks. Shall refine it in next version.
> BTW, No need of CC-ing me. I am not a maintainer of relevant subsystems.
Sure.

Thanks,
Anurup
> Best regards,
> Krzysztof

^ permalink raw reply

* [PATCH v2 2/2] power: bq27xxx_battery: add poll interval property query
From: Matt Ranostay @ 2016-11-04  5:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161102082206.GE21488@amd>

On Wed, Nov 2, 2016 at 1:22 AM, Pavel Machek <pavel@ucw.cz> wrote:
> Hi!
>
>> >> >> Better then previous one.
>> >> >>
>> >> >> But my version of bq27xxx_battery.c already contains this:
>> >> >
>> >> > This is for allowing udev rule to set the properties as well.
>> >> > otherwise a kinda crude RUN = " echo value >
>> >> > /sys/module/bq27xxx_battery/parameters/poll_interval" is required.
>> >>
>> >> Any thoughts on this?
>> >
>> > I'd say  echo value >
>> > /sys/module/bq27xxx_battery/parameters/poll_interval .. is quite
>> > adequate solution...?
>> >
>> > Alternatively, convince us that something else is useful for everyone,
>> > and we can do the right thing (poll more often when battery is nearly
>> > empty), automatically...
>>
>> Ok should have had the patchset set it per device, and not use the
>> global poll_interval. Of need to add some logic to see if uses the
>> global poll_interval or it's own setting.
>>
>> There are times where you could have multiple batteries connected to
>> multiple fuel gauges, and want to up the polling interval on certain
>> ones that are discharging at different rates.
>>
>> But of course I'll let you guys let me know if this seems useful at all.
>
> I agree per-device polling would be cleaner.
>

Ok I'll work something up for RFC.

> But unless you have hardware with more than one bq27xxx, I'd avoid the
> work...
>
> Now... its also possible that poll_interval should change itself
> (within kernel) to do the right thing.
>

True but that is state machine territory, but I'll worry about that later...

> Best regards,
>
>                                                                         Pavel
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* [PATCH v2 2/3] irqchip: mtk-cirq: Add mediatek mtk-cirq implement
From: Youlin Pei @ 2016-11-04  4:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <86twbrj586.fsf@arm.com>

On Tue, 2016-11-01 at 20:49 +0000, Marc Zyngier wrote:
> On Tue, Nov 01 2016 at 11:52:01 AM, Youlin Pei <youlin.pei@mediatek.com> wrote:
> > In Mediatek SOCs, the CIRQ is a low power interrupt controller
> > designed to works outside MCUSYS which comprises with Cortex-Ax
> > cores,CCI and GIC.
> >
> > The CIRQ controller is integrated in between MCUSYS( include
> > Cortex-Ax, CCI and GIC ) and interrupt sources as the second
> > level interrupt controller. The external interrupts which outside
> > MCUSYS will feed through CIRQ then bypass to GIC. CIRQ can monitors
> > all edge trigger interupts. When an edge interrupt is triggered,
> > CIRQ can record the status and generate a pulse signal to GIC when
> > flush command executed.
> >
> > When system enters sleep mode, MCUSYS will be turned off to improve
> > power consumption, also GIC is power down. The edge trigger interrupts
> > will be lost in this scenario without CIRQ.
> >
> > This commit provides the CIRQ irqchip implement.
> >
> > Signed-off-by: Youlin Pei <youlin.pei@mediatek.com>
> > ---
> >  drivers/irqchip/Makefile       |    2 +-
> >  drivers/irqchip/irq-mtk-cirq.c |  262 ++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 263 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/irqchip/irq-mtk-cirq.c
> >
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index e4dbfc8..8f33580 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -60,7 +60,7 @@ obj-$(CONFIG_BCM7120_L2_IRQ)		+= irq-bcm7120-l2.o
> >  obj-$(CONFIG_BRCMSTB_L2_IRQ)		+= irq-brcmstb-l2.o
> >  obj-$(CONFIG_KEYSTONE_IRQ)		+= irq-keystone.o
> >  obj-$(CONFIG_MIPS_GIC)			+= irq-mips-gic.o
> > -obj-$(CONFIG_ARCH_MEDIATEK)		+= irq-mtk-sysirq.o
> > +obj-$(CONFIG_ARCH_MEDIATEK)		+= irq-mtk-sysirq.o irq-mtk-cirq.o
> >  obj-$(CONFIG_ARCH_DIGICOLOR)		+= irq-digicolor.o
> >  obj-$(CONFIG_RENESAS_H8300H_INTC)	+= irq-renesas-h8300h.o
> >  obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
> > diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c
> > new file mode 100644
> > index 0000000..fc43ef3
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-mtk-cirq.c
> > @@ -0,0 +1,262 @@
> > +/*
> > + * Copyright (c) 2016 MediaTek Inc.
> > + * Author: Youlin.Pei <youlin.pei@mediatek.com>
> > + *
> > + * 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/irq.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +#include <linux/io.h>
> > +#include <linux/slab.h>
> > +#include <linux/syscore_ops.h>
> > +
> > +#define CIRQ_ACK	0x40
> > +#define CIRQ_MASK_SET	0xc0
> > +#define CIRQ_MASK_CLR	0x100
> > +#define CIRQ_SENS_SET	0x180
> > +#define CIRQ_SENS_CLR	0x1c0
> > +#define CIRQ_POL_SET	0x240
> > +#define CIRQ_POL_CLR	0x280
> > +#define CIRQ_CONTROL	0x300
> > +
> > +#define CIRQ_EN	0x1
> > +#define CIRQ_EDGE	0x2
> > +#define CIRQ_FLUSH	0x4
> > +
> > +#define CIRQ_IRQ_NUM    0x200
> > +
> > +struct mtk_cirq_chip_data {
> > +	void __iomem *base;
> > +	unsigned int ext_irq_start;
> > +};
> > +
> > +static struct mtk_cirq_chip_data *cirq_data;
> 
> Are you guaranteed that you'll only ever have a single CIRQ in any
> system?

In Mediatek's SOC, only hace a single CIRQ.

> 
> > +
> > +static void mtk_cirq_write_mask(struct irq_data *data, unsigned int offset)
> > +{
> > +	struct mtk_cirq_chip_data *chip_data = data->chip_data;
> > +	unsigned int cirq_num = data->hwirq;
> > +	u32 mask = 1 << (cirq_num % 32);
> > +
> > +	writel(mask, chip_data->base + offset + (cirq_num / 32) * 4);
> 
> Why can't you use the relaxed accessors?

It seems that i use wrong function, i will change the writel to
writel_relaxed in next version.

> 
> > +}
> > +
> > +static void mtk_cirq_mask(struct irq_data *data)
> > +{
> > +	mtk_cirq_write_mask(data, CIRQ_MASK_SET);
> > +	irq_chip_mask_parent(data);
> > +}
> > +
> > +static void mtk_cirq_unmask(struct irq_data *data)
> > +{
> > +	mtk_cirq_write_mask(data, CIRQ_MASK_CLR);
> > +	irq_chip_unmask_parent(data);
> > +}
> > +
> > +static void mtk_cirq_eoi(struct irq_data *data)
> > +{
> > +	mtk_cirq_write_mask(data, CIRQ_ACK);
> 
> EOI and ACK have very different semantics. What is this write actually
> doing? Also, you're now doing an additional MMIO write on each interrupt
> EOI, doubling its cost. Do you really need to do actually signal the HW
> that we've EOIed an interrupt? I would have hoped that you'd be able to
> put it in "bypass" mode as long as you're not suspending...
> 

When external interrupt happened, CIRQ status register record the status
even CIRQ is not enabled. when execute the flush command, CIRQ will
resend the signals according to the status. So if don't clear the
status, CIRQ will resend the wrong signals. the ACK write operation will
clear the status.

> > +	irq_chip_eoi_parent(data);
> > +}
> > +
> > +static int mtk_cirq_set_type(struct irq_data *data, unsigned int type)
> > +{
> > +	int ret;
> > +
> > +	switch (type & IRQ_TYPE_SENSE_MASK) {
> > +	case IRQ_TYPE_EDGE_FALLING:
> > +		mtk_cirq_write_mask(data, CIRQ_POL_CLR);
> > +		mtk_cirq_write_mask(data, CIRQ_SENS_CLR);
> > +		break;
> > +	case IRQ_TYPE_EDGE_RISING:
> > +		mtk_cirq_write_mask(data, CIRQ_POL_SET);
> > +		mtk_cirq_write_mask(data, CIRQ_SENS_CLR);
> > +		break;
> > +	case IRQ_TYPE_LEVEL_LOW:
> > +		mtk_cirq_write_mask(data, CIRQ_POL_CLR);
> > +		mtk_cirq_write_mask(data, CIRQ_SENS_SET);
> > +		break;
> > +	case IRQ_TYPE_LEVEL_HIGH:
> > +		mtk_cirq_write_mask(data, CIRQ_POL_SET);
> > +		mtk_cirq_write_mask(data, CIRQ_SENS_SET);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	data = data->parent_data;
> > +	ret = data->chip->irq_set_type(data, type);
> > +	return ret;
> > +}
> > +
> > +static struct irq_chip mtk_cirq_chip = {
> > +	.name			= "MT_CIRQ",
> > +	.irq_mask		= mtk_cirq_mask,
> > +	.irq_unmask		= mtk_cirq_unmask,
> > +	.irq_eoi		= mtk_cirq_eoi,
> > +	.irq_set_type		= mtk_cirq_set_type,
> > +	.irq_retrigger		= irq_chip_retrigger_hierarchy,
> > +#ifdef CONFIG_SMP
> > +	.irq_set_affinity	= irq_chip_set_affinity_parent,
> > +#endif
> > +};
> > +
> > +static int mtk_cirq_domain_translate(struct irq_domain *d,
> > +				     struct irq_fwspec *fwspec,
> > +				     unsigned long *hwirq,
> > +				     unsigned int *type)
> > +{
> > +	if (is_of_node(fwspec->fwnode)) {
> > +		if (fwspec->param_count != 3)
> > +			return -EINVAL;
> > +
> > +		/* No PPI should point to this domain */
> > +		if (fwspec->param[0] != 0)
> > +			return -EINVAL;
> > +
> > +		/* cirq support irq number check */
> > +		if (fwspec->param[1] < cirq_data->ext_irq_start)
> > +			return -EINVAL;
> > +
> > +		*hwirq = fwspec->param[1] - cirq_data->ext_irq_start;
> 
> What if the result is > CIRQ_IRQ_NUM?

will add CIRQ supported irq range in DT, and do range check here in next
version.

> 
> > +		*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
> > +		return 0;
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> > +
> > +static int mtk_cirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> > +				 unsigned int nr_irqs, void *arg)
> > +{
> > +	int i;
> > +	irq_hw_number_t hwirq;
> > +	struct irq_fwspec *fwspec = arg;
> > +	struct irq_fwspec parent_fwspec = *fwspec;
> > +
> > +	if (fwspec->param_count != 3)
> > +		return -EINVAL;
> > +
> > +	/* cirq doesn't support PPI */
> > +	if (fwspec->param[0])
> > +		return -EINVAL;
> > +
> > +	if (fwspec->param[1] < cirq_data->ext_irq_start)
> > +		return -EINVAL;
> > +
> > +	hwirq = fwspec->param[1] - cirq_data->ext_irq_start;
> 
> All this is a pure copy of mtk_cirq_domain_translate(). Please use it.

will fix in next version.

> > +	for (i = 0; i < nr_irqs; i++)
> > +		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> > +					      &mtk_cirq_chip,
> > +					      domain->host_data);
> 
> This is a bit silly. This loop only exists for the benefit of MSI
> support, which we're not dealing with here. So please stick a
> 
>          if (WARN_ON(nr_irqs != 1))
>          	return -EINVAL;
> 
> and drop the loop.

will fix in next version.

> 
> > +
> > +	parent_fwspec.fwnode = domain->parent->fwnode;
> > +	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
> > +					    &parent_fwspec);
> > +}
> > +
> > +static const struct irq_domain_ops cirq_domain_ops = {
> > +	.translate	= mtk_cirq_domain_translate,
> > +	.alloc		= mtk_cirq_domain_alloc,
> > +	.free		= irq_domain_free_irqs_common,
> > +};
> > +
> > +#ifdef CONFIG_PM_SLEEP
> > +static int mtk_cirq_suspend(void)
> > +{
> > +	u32 value;
> > +
> > +	/* set edge_only mode, record edge-triggerd interrupts */
> > +	/* enable cirq */
> > +	value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > +	value |= (CIRQ_EDGE | CIRQ_EN);
> > +	writel(value, cirq_data->base + CIRQ_CONTROL);
> 
> You're mixing relaxed and non-relaxed accessors. Why?

will change writel to writel_relaxed in next version.

> 
> > +	return 0;
> > +}
> > +
> > +static void mtk_cirq_resume(void)
> > +{
> > +	u32 value;
> > +
> > +	/* flush recored interrupts, will send signals to parent controller */
> > +	value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > +	writel(value | CIRQ_FLUSH, cirq_data->base + CIRQ_CONTROL);
> 
> Same remark.

will change writel to writel_relaxed in next version.

> 
> > +
> > +	/* disable cirq */
> > +	value = readl_relaxed(cirq_data->base + CIRQ_CONTROL);
> > +	value &= ~(CIRQ_EDGE | CIRQ_EN);
> > +	writel(value, cirq_data->base + CIRQ_CONTROL);
> 
> So from this, I infer that CIRQ is not enabled when the kernel is
> running (not suspended). It really makes me wonder why you need to do
> anything in the EOI callback.
> 
> > +}
> > +
> > +static struct syscore_ops mtk_cirq_syscore_ops = {
> > +	.suspend	= mtk_cirq_suspend,
> > +	.resume		= mtk_cirq_resume,
> > +};
> > +
> > +static void mtk_cirq_syscore_init(void)
> > +{
> > +	register_syscore_ops(&mtk_cirq_syscore_ops);
> > +}
> > +#else
> > +static inline void mtk_cirq_syscore_init(void) {}
> > +#endif
> > +
> > +static int __init mtk_cirq_of_init(struct device_node *node,
> > +				   struct device_node *parent)
> > +{
> > +	struct irq_domain *domain, *domain_parent;
> > +	int ret;
> > +
> > +	domain_parent = irq_find_host(parent);
> > +	if (!domain_parent) {
> > +		pr_err("mtk_cirq: interrupt-parent not found\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	cirq_data = kzalloc(sizeof(*cirq_data), GFP_KERNEL);
> > +	if (!cirq_data)
> > +		return -ENOMEM;
> > +
> > +	cirq_data->base = of_iomap(node, 0);
> > +	if (!cirq_data->base) {
> > +		pr_err("mtk_cirq: unable to map cirq register\n");
> > +		ret = -ENXIO;
> > +		goto out_free;
> > +	}
> > +
> > +	ret = of_property_read_u32(node, "mediatek,ext-irq-start",
> > +				   &cirq_data->ext_irq_start);
> > +	if (ret)
> > +		goto out_unmap;
> > +
> > +	domain = irq_domain_add_hierarchy(domain_parent, 0, CIRQ_IRQ_NUM, node,
> > +					  &cirq_domain_ops, cirq_data);
> 
> So you support at most 512 interrupts, and yet the GIC supports up to
> 987 SPIs. What happens for interrupt lines that out of the CIRQ range?
> Maybe having an explicit range in DT would be a good thing. That also
> brings back the question of having a single CIRQ in the system...
> 

In next version, i will add an explicit CIRQ supported range in DT.
Thanks a lot!

> > +	if (!domain) {
> > +		ret = -ENOMEM;
> > +		goto out_unmap;
> > +	}
> > +
> > +	mtk_cirq_syscore_init();
> > +
> > +	return 0;
> > +
> > +out_unmap:
> > +	iounmap(cirq_data->base);
> > +out_free:
> > +	kfree(cirq_data);
> > +	return ret;
> > +}
> > +
> > +IRQCHIP_DECLARE(mtk_cirq, "mediatek,mtk-cirq", mtk_cirq_of_init);
> 
> Thanks,
> 
> 	M.

^ permalink raw reply

* [RFC 0/8] KVM PCIe/MSI passthrough on ARM/ARM64 (Alt II)
From: Alex Williamson @ 2016-11-04  4:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478209178-3009-1-git-send-email-eric.auger@redhat.com>

On Thu,  3 Nov 2016 21:39:30 +0000
Eric Auger <eric.auger@redhat.com> wrote:

> Following Will & Robin's suggestions, this series attempts to propose
> an alternative to [1] where the host would arbitrarily decide the
> location of the IOVA MSI window and would be able to report to the
> userspace the list of reserved IOVA regions that cannot be used
> along with VFIO_IOMMU_MAP_DMA. This would allow the userspace to react
> in case of conflict.
> 
> Userspace can retrieve all the reserved regions through the VFIO_IOMMU_GET_INFO
> IOCTL by querying the new RESV_IOVA_RANGE chained capability. Each reserved
> IOVA range is put in a separate capability.

Doesn't it make more sense to describe the non-holes (ie. what I
can use for DMA) rather the holes (what I can't use for DMA)?  For
example on VT-d, the IOMMU not only has the block of MSI addresses
handled through interrupt remapping, but it also has a maximum address
width.  Rather than describing the reserved space we could describe the
usable DMA ranges above and below that reserved block.

Anyway, there's also a pretty harsh problem that I came up with in
talking to Will.  If the platform describes a fixed IOVA range as
reserved, that's great for the use case when a VM is instantiated with
a device attached, but it seems like it nearly excludes the case of
hotplugging a device.  We can't dynamically decide that a set of RAM
pages in the VM cannot be used as a DMA target.  Does the user need to
create the VM with a predefined hole that lines up with the reserved
regions for this platform?  How do they know the reserved regions for
this platform?  How would we handle migration where an assigned device
hot-add might not occur until after we've migrated to a slightly
different platform from the one we started on, that might have
different reserved memory requirements?

We can always have QEMU reject hot-adding the device if the reserved
region overlaps existing guest RAM, but I don't even really see how we
advise users to give them a reasonable chance of avoiding that
possibility.  Apparently there are also ARM platforms where MSI pages
cannot be remapped to support the previous programmable user/VM
address, is it even worthwhile to support those platforms?  Does that
decision influence whether user programmable MSI reserved regions are
really a second class citizen to fixed reserved regions?  I expect
we'll be talking about this tomorrow morning, but I certainly haven't
come up with any viable solutions to this.  Thanks,

Alex

> At IOMMU level, the reserved regions are stored in an iommu_domain list
> which is populated on each device attachment. An IOMMU add_reserved_regions
> callback specializes the registration of the reserved regions.
> 
> On x86, the [FEE0_0000h - FEF0_000h] MSI window is registered (NOT tested).
> 
> On ARM, the PCI host bridge windows (ACS check to be added?) + the MSI IOVA
> reserved regions are populated by the arm-smmu driver. Currently the MSI
> IOVA region is arbitrarily located at 0x8000000 and 1MB sized.  An IOVA domain
> is created in add_reserved_regions callback. Then MSIs are transparently
> mapped using this IOVA domain.
> 
> This series currently does not address some features addressed in [1]:
> - MSI IOVA size requirement computation
> - IRQ safety assessment
> 
> This RFC was just tested on ARM Overdrive with QEMU and is sent to help
> potential discussions at LPC. Additionnal development + testing is needed.
> 
> 2 tentative fixes may be submitted separately:
> - vfio: fix vfio_info_cap_add/shift
> - iommu/iova: fix __alloc_and_insert_iova_range
> 
> Best Regards
> 
> Eric
> 
> [1] [PATCH v14 00/16] KVM PCIe/MSI passthrough on ARM/ARM64
> https://lkml.org/lkml/2016/10/12/347
> 
> Git: complete series available at
> https://github.com/eauger/linux/tree/v4.9-rc3-reserved-rfc
> 
> 
> Eric Auger (7):
>   vfio: fix vfio_info_cap_add/shift
>   iommu/iova: fix __alloc_and_insert_iova_range
>   iommu: Add a list of iommu_reserved_region in iommu_domain
>   vfio/type1: Introduce RESV_IOVA_RANGE capability
>   iommu: Handle the list of reserved regions
>   iommu/vt-d: Implement add_reserved_regions callback
>   iommu/arm-smmu: implement add_reserved_regions callback
> 
> Robin Murphy (1):
>   iommu/dma: Allow MSI-only cookies
> 
>  drivers/iommu/arm-smmu.c        | 63 +++++++++++++++++++++++++++++++++++++++++
>  drivers/iommu/dma-iommu.c       | 39 +++++++++++++++++++++++++
>  drivers/iommu/intel-iommu.c     | 48 ++++++++++++++++++++++---------
>  drivers/iommu/iommu.c           | 25 ++++++++++++++++
>  drivers/iommu/iova.c            |  2 +-
>  drivers/vfio/vfio.c             |  5 ++--
>  drivers/vfio/vfio_iommu_type1.c | 63 ++++++++++++++++++++++++++++++++++++++++-
>  include/linux/dma-iommu.h       |  9 ++++++
>  include/linux/iommu.h           | 23 +++++++++++++++
>  include/uapi/linux/vfio.h       | 16 ++++++++++-
>  10 files changed, 275 insertions(+), 18 deletions(-)
> 

^ permalink raw reply

* [PATCH v2 4/6] pinctrl: aspeed: Read and write bits in LPCHC and GFX controllers
From: Andrew Jeffery @ 2016-11-04  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACPK8Xd1aisN4d2C01NXAYTZ1FW=C4b_hjvHce-RY9ReRq2cDw@mail.gmail.com>

On Fri, 2016-11-04 at 09:54 +1030, Joel Stanley wrote:
> On Thu, Nov 3, 2016 at 1:07 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> > 
> > The System Control Unit IP block in the Aspeed SoCs is typically where
> > the pinmux configuration is found, but not always. A number of pins
> > depend on state in one of LPC Host Control (LPCHC) or SoC Display
> > Controller (GFX) IP blocks, so the Aspeed pinmux drivers should have the
> > means to adjust these as necessary.
> > 
> > We use syscon to cast a regmap over the GFX and LPCHCR blocks, which is
> > used as an arbitration layer between the relevant driver and the pinctrl
> > subsystem. The regmaps are then exposed to the SoC-specific pinctrl
> > drivers by phandles in the devicetree, and are selected during a mux
> > request by querying a new 'ip' member in struct aspeed_sig_desc.
> > 
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> I like this a lot more than the first go. Good work.
> 
> Some minor comments below.
> 
> > 
> > ---
> > Since v1:
> > 
> > The change is now proactive: instead of reporting that we need to flip bits in
> > controllers we can't access, the patch provides access via regmaps for the
> > relevant controllers. The implementation also splits out the IP block ID into
> > its own variable rather than packing the value into the upper bits of the reg
> > member of struct aspeed_sig_desc. This drives some churn in the diff, but I've
> > tried to minimise it.
> > 
> > ?.../devicetree/bindings/pinctrl/pinctrl-aspeed.txt | 50 +++++++++++++---
> > ?drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c?????????| 18 +++---
> > ?drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c?????????| 39 ++++++++++---
> > ?drivers/pinctrl/aspeed/pinctrl-aspeed.c????????????| 66 +++++++++++++---------
> > ?drivers/pinctrl/aspeed/pinctrl-aspeed.h????????????| 32 ++++++++---
> > ?5 files changed, 144 insertions(+), 61 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> > index 2ad18c4ea55c..115b0cce6c1c 100644
> > --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> > @@ -4,12 +4,19 @@ Aspeed Pin Controllers
> > ?The Aspeed SoCs vary in functionality inside a generation but have a common mux
> > ?device register layout.
> > 
> > -Required properties:
> > -- compatible : Should be any one of the following:
> > -???????????????"aspeed,ast2400-pinctrl"
> > -???????????????"aspeed,g4-pinctrl"
> > -???????????????"aspeed,ast2500-pinctrl"
> > -???????????????"aspeed,g5-pinctrl"
> > +Required properties for g4:
> > +- compatible :?????????????????????????Should be any one of the following:
> > +???????????????????????????????"aspeed,ast2400-pinctrl"
> > +???????????????????????????????"aspeed,g4-pinctrl"
> > +
> > +Required properties for g5:
> > +- compatible :?????????????????????????Should be any one of the following:
> > +???????????????????????????????"aspeed,ast2500-pinctrl"
> > +???????????????????????????????"aspeed,g5-pinctrl"
> > +
> > +- aspeed,external-nodes:???????A cell of phandles to external controller nodes:
> > +???????????????????????????????0: compatible with "aspeed,ast2500-gfx", "syscon"
> > +???????????????????????????????1: compatible with "aspeed,ast2500-lpchc", "syscon"
> > 
> > ?The pin controller node should be a child of a syscon node with the required
> > ?property:
> > @@ -47,7 +54,7 @@ RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 SPI1DEBUG SPI1PASSTHRU TIMER4 TIMER5 TIMER6
> > ?TIMER7 TIMER8 VGABIOSROM
> > 
> > 
> > -Examples:
> > +g4 Example:
> > 
> > ?syscon: scu at 1e6e2000 {
> > ????????compatible = "syscon", "simple-mfd";
> > @@ -63,5 +70,34 @@ syscon: scu at 1e6e2000 {
> > ????????};
> > ?};
> > 
> > +g5 Example:
> > +
> > +apb {
> > +???????gfx: display at 1e6e6000 {
> > +???????????????compatible = "aspeed,ast2500-gfx", "syscon";
> > +???????????????reg = <0x1e6e6000 0x1000>;
> > +???????};
> > +
> > +???????lpchc: lpchc at 1e7890a0 {
> > +???????????????compatible = "aspeed,ast2500-lpchc", "syscon";
> > +???????????????reg = <0x1e7890a0 0xc4>;
> > +???????};
> > +
> > +???????syscon: scu at 1e6e2000 {
> > +???????????????compatible = "syscon", "simple-mfd";
> > +???????????????reg = <0x1e6e2000 0x1a8>;
> > +
> > +???????????????pinctrl: pinctrl {
> > +???????????????????????compatible = "aspeed,g5-pinctrl";
> > +???????????????????????aspeed,external-nodes = <&gfx, &lpchc>;
> > +
> > +???????????????????????pinctrl_i2c3_default: i2c3_default {
> > +???????????????????????????????function = "I2C3";
> > +???????????????????????????????groups = "I2C3";
> > +???????????????????????};
> > +???????????????};
> > +???????};
> > +};
> > +
> > ?Please refer to pinctrl-bindings.txt in this directory for details of the
> > ?common pinctrl bindings used by client devices.
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> > index a21b071ff290..558bd102416c 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> > @@ -292,7 +292,7 @@ SSSF_PIN_DECL(U18, GPIOG7, FLWP, SIG_DESC_SET(SCU84, 7));
> > ?#define UART6_DESC?????SIG_DESC_SET(SCU90, 7)
> > ?#define ROM16_DESC?????SIG_DESC_SET(SCU90, 6)
> > ?#define FLASH_WIDE?????SIG_DESC_SET(HW_STRAP1, 4)
> > -#define BOOT_SRC_NOR???{ HW_STRAP1, GENMASK(1, 0), 0, 0 }
> > +#define BOOT_SRC_NOR???{ ASPEED_IP_SCU, HW_STRAP1, GENMASK(1, 0), 0, 0 }
> > 
> > ?#define A8 56
> > ?SIG_EXPR_DECL(ROMD8, ROM16, ROM16_DESC);
> > @@ -418,9 +418,9 @@ FUNC_GROUP_DECL(I2C8, G5, F3);
> > ?#define U1 88
> > ?SSSF_PIN_DECL(U1, GPIOL0, NCTS1, SIG_DESC_SET(SCU84, 16));
> > 
> > -#define VPI18_DESC?????{ SCU90, GENMASK(5, 4), 1, 0 }
> > -#define VPI24_DESC?????{ SCU90, GENMASK(5, 4), 2, 0 }
> > -#define VPI30_DESC?????{ SCU90, GENMASK(5, 4), 3, 0 }
> > +#define VPI18_DESC?????{ ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 }
> > +#define VPI24_DESC?????{ ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 }
> > +#define VPI30_DESC?????{ ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 }
> > 
> > ?#define T5 89
> > ?#define T5_DESC?????????SIG_DESC_SET(SCU84, 17)
> > @@ -641,11 +641,11 @@ SSSF_PIN_DECL(Y22, GPIOR2, ROMCS3, SIG_DESC_SET(SCU88, 26));
> > ?#define U19 139
> > ?SSSF_PIN_DECL(U19, GPIOR3, ROMCS4, SIG_DESC_SET(SCU88, 27));
> > 
> > -#define VPOOFF0_DESC???{ SCU94, GENMASK(1, 0), 0, 0 }
> > -#define VPO12_DESC?????{ SCU94, GENMASK(1, 0), 1, 0 }
> > -#define VPO24_DESC?????{ SCU94, GENMASK(1, 0), 2, 0 }
> > -#define VPOOFF1_DESC???{ SCU94, GENMASK(1, 0), 3, 0 }
> > -#define VPO_OFF_12??????{ SCU94, 0x2, 0, 0 }
> > +#define VPOOFF0_DESC???{ ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 }
> > +#define VPO12_DESC?????{ ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 1, 0 }
> > +#define VPO24_DESC?????{ ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 2, 0 }
> > +#define VPOOFF1_DESC???{ ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 3, 0 }
> > +#define VPO_OFF_12??????{ ASPEED_IP_SCU, SCU94, 0x2, 0, 0 }
> > ?#define VPO_24_OFF??????SIG_DESC_SET(SCU94, 1)
> > 
> > ?#define V21 140
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> > index 87b46390b695..99c4fa9bf861 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> > @@ -10,6 +10,7 @@
> > ?#include 
> > ?#include 
> > ?#include 
> > +#include 
> > ?#include 
> > ?#include 
> > ?#include 
> > @@ -26,8 +27,8 @@
> > 
> > ?#define ASPEED_G5_NR_PINS 228
> > 
> > -#define COND1??????????{ SCU90, BIT(6), 0, 0 }
> > -#define COND2??????????{ SCU94, GENMASK(1, 0), 0, 0 }
> > +#define COND1??????????{ ASPEED_IP_SCU, SCU90, BIT(6), 0, 0 }
> > +#define COND2??????????{ ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 }
> > 
> > ?#define B14 0
> > ?SSSF_PIN_DECL(B14, GPIOA0, MAC1LINK, SIG_DESC_SET(SCU80, 0));
> > @@ -186,9 +187,12 @@ MS_PIN_DECL(C20, GPIOE1, NDCD3, GPIE0OUT);
> > 
> > ?FUNC_GROUP_DECL(GPIE0, B20, C20);
> > 
> > -#define SPI1_DESC??????????????{ HW_STRAP1, GENMASK(13, 12), 1, 0 }
> > -#define SPI1DEBUG_DESC?????????{ HW_STRAP1, GENMASK(13, 12), 2, 0 }
> > -#define SPI1PASSTHRU_DESC??????{ HW_STRAP1, GENMASK(13, 12), 3, 0 }
> > +#define SPI1_DESC \
> > +???????{ ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 1, 0 }
> > +#define SPI1DEBUG_DESC \
> > +???????{ ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 2, 0 }
> > +#define SPI1PASSTHRU_DESC \
> > +???????{ ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 3, 0 }
> > 
> > ?#define C18 64
> > ?SIG_EXPR_DECL(SYSCS, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> > @@ -325,10 +329,11 @@ SS_PIN_DECL(R1, GPIOK7, SDA8);
> > 
> > ?FUNC_GROUP_DECL(I2C8, P2, R1);
> > 
> > -#define VPIOFF0_DESC????{ SCU90, GENMASK(5, 4), 0, 0 }
> > -#define VPIOFF1_DESC????{ SCU90, GENMASK(5, 4), 1, 0 }
> > -#define VPI24_DESC??????{ SCU90, GENMASK(5, 4), 2, 0 }
> > -#define VPIRSVD_DESC????{ SCU90, GENMASK(5, 4), 3, 0 }
> > +#define VPIOFF0_DESC????{ ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 0, 0 }
> > +#define VPIOFF1_DESC????{ ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 }
> > +#define VPI24_DESC??????{ ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 }
> > +#define VPIRSVD_DESC????{ ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 }
> > +
> > 
> > ?#define V2 104
> > ?#define V2_DESC?????????SIG_DESC_SET(SCU88, 0)
> > @@ -848,10 +853,26 @@ static struct pinctrl_desc aspeed_g5_pinctrl_desc = {
> > ?static int aspeed_g5_pinctrl_probe(struct platform_device *pdev)
> > ?{
> > ????????int i;
> > +???????struct regmap **map;
> > +???????struct device_node *node;
> > 
> > ????????for (i = 0; i < ARRAY_SIZE(aspeed_g5_pins); i++)
> > ????????????????aspeed_g5_pins[i].number = i;
> > 
> > +???????map = &aspeed_g5_pinctrl_data.maps[ASPEED_IP_GFX];
> > +???????node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 0);
> > +???????*map = syscon_node_to_regmap(node);
> I think you can use syscon_regmap_lookup_by_phandle to replace both of
> these lines.

Good call, will do.

> 
> > 
> > +???????of_node_put(node);
> > +???????if (IS_ERR(*map))
> > +???????????????return PTR_ERR(*map);
> Do we want to fail, or warn and continue?

We would need to add further checks to defend against null dereferences
if we were to continue. I think the broken devicetree should be fixed.

> 
> The sequence is a bit messy. How about:
> 
> struct regmap *map;
> 
> map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> "aspeed,external-nodes");
> if (IS_ERR(map))
> ???return PTR_ERR(map);
> 
> aspeed_g5_pinctrl_data.maps[ASPEED_IP_GFX] = map;

That looks neater, I will switch.

> 
> 
> > 
> > +
> > +???????map = &aspeed_g5_pinctrl_data.maps[ASPEED_IP_LPCHC];
> > +???????node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 1);
> > +???????*map = syscon_node_to_regmap(node);
> > +???????of_node_put(node);
> > +???????if (IS_ERR(*map))
> > +???????????????return PTR_ERR(*map);
> > +
> Same comments as above.

Ack.

> 
> > 
> > ????????return aspeed_pinctrl_probe(pdev, &aspeed_g5_pinctrl_desc,
> > ????????????????????????&aspeed_g5_pinctrl_data);
> > ?}
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> > index 49aeba912531..23586aac7a5a 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> > @@ -14,6 +14,12 @@
> > ?#include "../core.h"
> > ?#include "pinctrl-aspeed.h"
> > 
> > +static const char *const aspeed_pinmux_ips[] = {
> > +???????[ASPEED_IP_SCU] = "SCU",
> > +???????[ASPEED_IP_GFX] = "GFX",
> > +???????[ASPEED_IP_LPCHC] = "LHCR",
> We've got both LPCHC and LHCR here. As I said when commenting on the
> regmap bindings, I like LHC(R) better.
> 
> > 
> > +};
> > +
> > ?int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
> > ?{
> > ????????struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
> > @@ -78,7 +84,8 @@ int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
> > ?static inline void aspeed_sig_desc_print_val(
> > ????????????????const struct aspeed_sig_desc *desc, bool enable, u32 rv)
> What's a rv? Perhaps "reg" or "value"?
> 
> > 
> > ?{
> > -???????pr_debug("SCU%x[0x%08x]=0x%x, got 0x%x from 0x%08x\n", desc->reg,
> > +???????pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n",
> > +???????????????????????aspeed_pinmux_ips[desc->ip], desc->reg,
> > ????????????????????????desc->mask, enable ? desc->enable : desc->disable,
> > ????????????????????????(rv & desc->mask) >> __ffs(desc->mask), rv);
> > ?}
> > @@ -88,7 +95,7 @@ static inline void aspeed_sig_desc_print_val(
> > ? *
> > ? * @desc: The signal descriptor of interest
> > ? * @enabled: True to query the enabled state, false to query disabled state
> > - * @regmap: The SCU regmap instance
> > + * @regmap: The IP block's regmap instance
> > ? *
> > ? * @return True if the descriptor's bitfield is configured to the state
> > ? * selected by @enabled, false otherwise
> > @@ -119,7 +126,7 @@ static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
> > ? *
> > ? * @expr: An expression controlling the signal for a mux function on a pin
> > ? * @enabled: True to query the enabled state, false to query disabled state
> > - * @regmap: The SCU regmap instance
> > + * @maps: The list of regmap instances
> > ? *
> > ? * @return True if the expression composed by @enabled evaluates true, false
> > ? * otherwise
> > @@ -136,15 +143,16 @@ static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
> > ? * either condition as required.
> > ? */
> > ?static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
> > -????????????????????????????????bool enabled, struct regmap *map)
> > +????????????????????????????????bool enabled, struct regmap * const *maps)
> > ?{
> > ????????int i;
> > 
> > ????????for (i = 0; i < expr->ndescs; i++) {
> > ????????????????const struct aspeed_sig_desc *desc = &expr->descs[i];
> > 
> > -???????????????if (!aspeed_sig_desc_eval(desc, enabled, map))
> > +???????????????if (!aspeed_sig_desc_eval(desc, enabled, maps[desc->ip]))
> > ????????????????????????return false;
> > +
> > ????????}
> > 
> > ????????return true;
> > @@ -158,12 +166,12 @@ static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
> > ? *????????configured
> > ? * @enable: true to enable an function's signal through a pin's signal
> > ? *??????????expression, false to disable the function's signal
> > - * @map: The SCU's regmap instance for pinmux register access.
> > + * @maps: The list of regmap instances for pinmux register access.
> > ? *
> > ? * @return true if the expression is configured as requested, false otherwise
> > ? */
> > ?static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> > -???????????????????????????????bool enable, struct regmap *map)
> > +???????????????????????????????bool enable, struct regmap * const *maps)
> > ?{
> > ????????int i;
> > 
> > @@ -171,6 +179,7 @@ static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> > ????????????????bool ret;
> > ????????????????const struct aspeed_sig_desc *desc = &expr->descs[i];
> > ????????????????u32 pattern = enable ? desc->enable : desc->disable;
> > +???????????????u32 val = (pattern << __ffs(desc->mask));
> > 
> > ????????????????/*
> > ?????????????????* Strap registers are configured in hardware or by early-boot
> > @@ -179,48 +188,49 @@ static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> > ?????????????????* deconfigured and is the reason we re-evaluate after writing
> > ?????????????????* all descriptor bits.
> > ?????????????????*/
> > -???????????????if (desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2)
> > +???????????????if ((desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2) &&
> > +???????????????????????????????desc->ip == ASPEED_IP_SCU)
> > ????????????????????????continue;
> > 
> > -???????????????ret = regmap_update_bits(map, desc->reg, desc->mask,
> > -???????????????????????????????pattern << __ffs(desc->mask)) == 0;
> > +???????????????ret = regmap_update_bits(maps[desc->ip], desc->reg,
> > +????????????????????????????????????????desc->mask, val) == 0;
> > 
> > ????????????????if (!ret)
> > ????????????????????????return ret;
> > ????????}
> > 
> > -???????return aspeed_sig_expr_eval(expr, enable, map);
> > +???????return aspeed_sig_expr_eval(expr, enable, maps);
> > ?}
> > 
> > ?static bool aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr,
> > -??????????????????????????????????struct regmap *map)
> > +??????????????????????????????????struct regmap * const *maps)
> > ?{
> > -???????if (aspeed_sig_expr_eval(expr, true, map))
> > +???????if (aspeed_sig_expr_eval(expr, true, maps))
> > ????????????????return true;
> > 
> > -???????return aspeed_sig_expr_set(expr, true, map);
> > +???????return aspeed_sig_expr_set(expr, true, maps);
> > ?}
> > 
> > ?static bool aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr,
> > -???????????????????????????????????struct regmap *map)
> > +???????????????????????????????????struct regmap * const *maps)
> > ?{
> > -???????if (!aspeed_sig_expr_eval(expr, true, map))
> > +???????if (!aspeed_sig_expr_eval(expr, true, maps))
> > ????????????????return true;
> > 
> > -???????return aspeed_sig_expr_set(expr, false, map);
> > +???????return aspeed_sig_expr_set(expr, false, maps);
> > ?}
> > 
> > ?/**
> > ? * Disable a signal on a pin by disabling all provided signal expressions.
> > ? *
> > ? * @exprs: The list of signal expressions (from a priority level on a pin)
> > - * @map: The SCU's regmap instance for pinmux register access.
> > + * @maps: The list of regmap instances for pinmux register access.
> > ? *
> > ? * @return true if all expressions in the list are successfully disabled, false
> > ? * otherwise
> > ? */
> > ?static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
> > -??????????????????????????????struct regmap *map)
> > +??????????????????????????????struct regmap * const *maps)
> > ?{
> > ????????bool disabled = true;
> > 
> > @@ -230,7 +240,7 @@ static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
> > ????????while (*exprs) {
> > ????????????????bool ret;
> > 
> > -???????????????ret = aspeed_sig_expr_disable(*exprs, map);
> > +???????????????ret = aspeed_sig_expr_disable(*exprs, maps);
> > ????????????????disabled = disabled && ret;
> > 
> > ????????????????exprs++;
> > @@ -343,6 +353,8 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> > ????????????????const struct aspeed_sig_expr **funcs;
> > ????????????????const struct aspeed_sig_expr ***prios;
> > 
> > +???????????????pr_debug("Muxing pin %d for %s\n", pin, pfunc->name);
> > +
> > ????????????????if (!pdesc)
> > ????????????????????????return -EINVAL;
> > 
> > @@ -358,7 +370,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> > ????????????????????????if (expr)
> > ????????????????????????????????break;
> > 
> > -???????????????????????if (!aspeed_disable_sig(funcs, pdata->map))
> > +???????????????????????if (!aspeed_disable_sig(funcs, pdata->maps))
> > ????????????????????????????????return -EPERM;
> > 
> > ????????????????????????prios++;
> > @@ -377,7 +389,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> > ????????????????????????return -ENXIO;
> > ????????????????}
> > 
> > -???????????????if (!aspeed_sig_expr_enable(expr, pdata->map))
> > +???????????????if (!aspeed_sig_expr_enable(expr, pdata->maps))
> > ????????????????????????return -EPERM;
> > ????????}
> > 
> > @@ -432,7 +444,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
> > ????????????????if (aspeed_gpio_in_exprs(funcs))
> > ????????????????????????break;
> > 
> > -???????????????if (!aspeed_disable_sig(funcs, pdata->map))
> > +???????????????if (!aspeed_disable_sig(funcs, pdata->maps))
> > ????????????????????????return -EPERM;
> > 
> > ????????????????prios++;
> > @@ -462,7 +474,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
> > ?????????* If GPIO is not the lowest priority signal type, assume there is only
> > ?????????* one expression defined to enable the GPIO function
> > ?????????*/
> > -???????if (!aspeed_sig_expr_enable(expr, pdata->map))
> > +???????if (!aspeed_sig_expr_enable(expr, pdata->maps))
> > ????????????????return -EPERM;
> > 
> > ????????return 0;
> > @@ -481,10 +493,10 @@ int aspeed_pinctrl_probe(struct platform_device *pdev,
> > ????????????????return -ENODEV;
> > ????????}
> > 
> > -???????pdata->map = syscon_node_to_regmap(parent->of_node);
> > -???????if (IS_ERR(pdata->map)) {
> > +???????pdata->maps[ASPEED_IP_SCU] = syscon_node_to_regmap(parent->of_node);
> > +???????if (IS_ERR(pdata->maps[ASPEED_IP_SCU])) {
> > ????????????????dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
> > -???????????????return PTR_ERR(pdata->map);
> > +???????????????return PTR_ERR(pdata->maps[ASPEED_IP_SCU]);
> > ????????}
> > 
> > ????????pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
> > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.h b/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> > index 3e72ef8c54bf..727728b86c07 100644
> > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> > @@ -232,6 +232,11 @@
> > ? * group.
> > ? */
> > 
> > +#define ASPEED_IP_SCU??0
> > +#define ASPEED_IP_GFX??1
> > +#define ASPEED_IP_LPCHC????????2
> > +#define ASPEED_NR_PINMUX_IPS???3
> > +
> > ?/*
> > ? * The "Multi-function Pins Mapping and Control" table in the SoC datasheet
> > ? * references registers by the device/offset mnemonic. The register macros
> > @@ -261,7 +266,9 @@
> > ???* A signal descriptor, which describes the register, bits and the
> > ???* enable/disable values that should be compared or written.
> > ???*
> > -??* @reg: The register offset from base in bytes
> > +??* @ip: The IP block identifier, used as an index into the regmap array in
> > +??*??????struct aspeed_pinctrl_data
> > +??* @reg: The register offset with respect to the base address of the IP block
> > ???* @mask: The mask to apply to the register. The lowest set bit of the mask is
> > ???*????????used to derive the shift value.
> > ???* @enable: The value that enables the function. Value should be in the LSBs,
> > @@ -270,6 +277,7 @@
> > ???*???????????LSBs, not at the position of the mask.
> > ???*/
> > ?struct aspeed_sig_desc {
> > +???????unsigned int ip;
> > ????????unsigned int reg;
> > ????????u32 mask;
> > ????????u32 enable;
> > @@ -313,24 +321,30 @@ struct aspeed_pin_desc {
> > 
> > ?/* Macro hell */
> > 
> > +#define SIG_DESC_IP_BIT(ip, reg, idx, val) \
> > +???????{ ip, reg, BIT_MASK(idx), val, (((val) + 1) & 1) }
> > +
> > ?/**
> > - * Short-hand macro for describing a configuration enabled by the state of one
> > - * bit. The disable value is derived.
> > + * Short-hand macro for describing an SCU descriptor enabled by the state of
> > + * one bit. The disable value is derived.
> > ? *
> > ? * @reg: The signal's associated register, offset from base
> > ? * @idx: The signal's bit index in the register
> > ? * @val: The value (0 or 1) that enables the function
> > ? */
> > ?#define SIG_DESC_BIT(reg, idx, val) \
> > -???????{ reg, BIT_MASK(idx), val, (((val) + 1) & 1) }
> > +???????SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, val)
> > +
> > +#define SIG_DESC_IP_SET(ip, reg, idx) SIG_DESC_IP_BIT(ip, reg, idx, 1)
> > 
> > ?/**
> > - * A further short-hand macro describing a configuration enabled with a set bit.
> > + * A further short-hand macro expanding to an SCU descriptor enabled by a set
> > + * bit.
> > ? *
> > - * @reg: The configuration's associated register, offset from base
> > - * @idx: The configuration's bit index in the register
> > + * @reg: The register, offset from base
> > + * @idx: The bit index in the register
> > ? */
> > -#define SIG_DESC_SET(reg, idx) SIG_DESC_BIT(reg, idx, 1)
> > +#define SIG_DESC_SET(reg, idx) SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, 1)
> > 
> > ?#define SIG_DESC_LIST_SYM(sig, func) sig_descs_ ## sig ## _ ## func
> > ?#define SIG_DESC_LIST_DECL(sig, func, ...) \
> > @@ -500,7 +514,7 @@ struct aspeed_pin_desc {
> > ????????MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(gpio))
> > 
> > ?struct aspeed_pinctrl_data {
> > -???????struct regmap *map;
> > +???????struct regmap *maps[ASPEED_NR_PINMUX_IPS];
> > 
> > ????????const struct pinctrl_pin_desc *pins;
> > ????????const unsigned int npins;
> > --
> > 2.7.4
> > 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161104/a6f587a0/attachment-0001.sig>

^ permalink raw reply

* [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching of bypass entries
From: Nipun Gupta @ 2016-11-04  3:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <VI1PR0401MB263890564BC836B7BBE744018DA30@VI1PR0401MB2638.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Stuart Yoder
> Sent: Friday, November 04, 2016 2:27
> To: Nipun Gupta <nipun.gupta@nxp.com>; robin.murphy at arm.com;
> will.deacon at arm.com; linux-arm-kernel at lists.infradead.org;
> iommu at lists.linux-foundation.org
> Cc: Nipun Gupta <nipun.gupta@nxp.com>
> Subject: RE: [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable
> caching of bypass entries
> 
> 
> 
> > -----Original Message-----
> > From: Nipun Gupta [mailto:nipun.gupta at nxp.com]
> > Sent: Thursday, November 03, 2016 7:27 PM
> > To: robin.murphy at arm.com; will.deacon at arm.com;
> > linux-arm-kernel at lists.infradead.org; iommu at lists.linux-
> > foundation.org
> > Cc: Stuart Yoder <stuart.yoder@nxp.com>; Nipun Gupta
> > <nipun.gupta@nxp.com>
> > Subject: [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable
> > caching of bypass entries
> 
> When you respin a patch, put the version number in the patch subject:
> 
>    [PATCH v2] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching
> of bypass entries

I added that first, but in the last moment used git format-patch after minor updates
and somehow missed it in the final patch :/. Re-spinning v3 with correct version number.

Thanks,
Nipun

> 
> Stuart

^ permalink raw reply

* [PATCH v2 3/6] mfd: dt: Add bindings for the Aspeed LPC Host Controller (LPCHC)
From: Andrew Jeffery @ 2016-11-04  3:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACPK8XezumurK6TStNhmTnHdhoJuZBzkJrS3iOArKz1tf1=nLw@mail.gmail.com>

On Fri, 2016-11-04 at 09:36 +1030, Joel Stanley wrote:
> On Thu, Nov 3, 2016 at 1:07 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> > 
> > The Aspeed LPC Host Controller is presented as a syscon device to
> > arbitrate access by LPC and pinmux drivers. LPC pinmux configuration on
> > fifth generation SoCs depends on bits in both the System Control Unit
> > and the LPC Host Controller.
> > 
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> > ?Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt | 17 +++++++++++++++++
> > ?1 file changed, 17 insertions(+)
> > ?create mode 100644 Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt
> > new file mode 100644
> > index 000000000000..792651488c3d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt
> > @@ -0,0 +1,17 @@
> > +* Device tree bindings for the Aspeed LPC Host Controller (LPCHC)
> I had to check the data sheet for that acronym. They call the
> registers LHC. I somewhat prefer that name, but if you're happy with
> it as-is then that's fine.

I had an internal debate about this. I figured LPCHC might give a bit
more context to the acronym. I'm not unhappy with it but I wouldn't
claim I'm happy either. I will change it to LHC since you somewhat
prefer it, and it better aligns with the datasheet.

> 
> I assume this is not an issue on the g4/ast2400?

Correct, we don't have the issue of pinmux needing to reach into the
LPC IO space on the AST2400. I don't think we've had anything else to
drive us to looking at the host controller space there, so I wasn't
going to add it to the bindings yet.

> 
> > 
> > +
> > +The LPCHC registers configure LPC behaviour between the BMC and the host
> > +system. The LPCHC also participates in pinmux requests on g5 SoCs and is
> > +therefore considered a syscon device.
> > +
> > +Required properties:
> > +- compatible:??????????"aspeed,ast2500-lpchc", "syscon"
> > +- reg:?????????????????contains offset/length value of the LPCHC memory
> > +???????????????????????region.
> > +
> > +Example:
> > +
> > +lpchc: lpchc at 1e7890a0 {
> > +???????compatible = "aspeed,ast2500-lpchc", "syscon";
> > +???????reg = <0x1e7890a0 0xc4>;
> Where's the 0xc4 come from? I can see 9 registers, which would mean
> the length should be 0x24?

Yes, it should be 0x24. I can't even claim that 'c' is near '2'. Thanks
for catching that.

Andrew

> 
> Cheers,
> 
> Joel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161104/19c05671/attachment.sig>

^ permalink raw reply

* [PATCH v4 4/4] ARM: dts: da850: Add the usb otg device node
From: David Lechner @ 2016-11-04  3:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478188752-22447-5-git-send-email-abailon@baylibre.com>

On 11/03/2016 10:59 AM, Alexandre Bailon wrote:
> This adds the device tree node for the usb otg
> controller present in the da850 family of SoC's.
> This also enables the otg usb controller for the lcdk board.
>
> Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
> ---
>  arch/arm/boot/dts/da850-lcdk.dts |  8 ++++++++
>  arch/arm/boot/dts/da850.dtsi     | 15 +++++++++++++++
>  2 files changed, 23 insertions(+)
>
> diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
> index 7b8ab21..9f5040c 100644
> --- a/arch/arm/boot/dts/da850-lcdk.dts
> +++ b/arch/arm/boot/dts/da850-lcdk.dts
> @@ -158,6 +158,14 @@
>  	rx-num-evt = <32>;
>  };
>
> +&usb_phy {
> +	status = "okay";
> +	};
> +
> +&usb0 {
> +	status = "okay";
> +};
> +
>  &aemif {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&nand_pins>;
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index f79e1b9..322a31a 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -372,6 +372,21 @@
>  					>;
>  			status = "disabled";
>  		};
> +		usb_phy: usb-phy {
> +			compatible = "ti,da830-usb-phy";
> +			#phy-cells = <1>;
> +			status = "disabled";
> +		};

The usb_phy node is already in the device tree as a child of the cfgchip 
syscon node[1]. It needs to be removed from this patch, otherwise we 
will end up with duplicate usb_phy nodes.

[1]: 
https://git.kernel.org/cgit/linux/kernel/git/nsekhar/linux-davinci.git/commit/?h=v4.10/dt&id=1b499f255589204466d8f8ab26e6b577d7b5c88f

> +		usb0: usb at 200000 {
> +			compatible = "ti,da830-musb";
> +			reg = <0x200000 0x10000>;
> +			interrupts = <58>;
> +			interrupt-names = "mc";
> +			dr_mode = "otg";

Isn't this the default value? Could we omit the dr_mode property here?

> +			phys = <&usb_phy 0>;
> +			phy-names = "usb-phy";
> +			status = "disabled";
> +		};
>  		gpio: gpio at 226000 {
>  			compatible = "ti,dm6441-gpio";
>  			gpio-controller;
>

^ permalink raw reply

* [PATCH 4/4] ARM: EXYNOS: Remove unused soc_is_exynos{4,5}
From: Pankaj Dubey @ 2016-11-04  3:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478230764-13748-1-git-send-email-pankaj.dubey@samsung.com>

As no more user of soc_is_exynos{4,5} we can safely remove them.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/common.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 9424a8a..d19064b 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -105,11 +105,6 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
 # define soc_is_exynos5800()	0
 #endif
 
-#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4212() || \
-			  soc_is_exynos4412())
-#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
-			  soc_is_exynos5420() || soc_is_exynos5800())
-
 extern u32 cp15_save_diag;
 extern u32 cp15_save_power;
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH 3/4] ARM: EXYNOS: Remove static mapping of SCU SFR
From: Pankaj Dubey @ 2016-11-04  3:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478230764-13748-1-git-send-email-pankaj.dubey@samsung.com>

Lets remove static mapping of SCU SFR mainly used in CORTEX-A9 SoC based boards.
Instead use mapping from device tree node of SCU.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/exynos.c                | 22 ----------------------
 arch/arm/mach-exynos/include/mach/map.h      |  2 --
 arch/arm/mach-exynos/platsmp.c               | 18 +++++++++++-------
 arch/arm/mach-exynos/pm.c                    | 14 +++++++++++---
 arch/arm/mach-exynos/suspend.c               | 15 +++++++++++----
 arch/arm/plat-samsung/include/plat/map-s5p.h |  4 ----
 6 files changed, 33 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 757fc11..fa08ef9 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -28,15 +28,6 @@
 
 #include "common.h"
 
-static struct map_desc exynos4_iodesc[] __initdata = {
-	{
-		.virtual	= (unsigned long)S5P_VA_COREPERI_BASE,
-		.pfn		= __phys_to_pfn(EXYNOS4_PA_COREPERI),
-		.length		= SZ_8K,
-		.type		= MT_DEVICE,
-	},
-};
-
 static struct platform_device exynos_cpuidle = {
 	.name              = "exynos_cpuidle",
 #ifdef CONFIG_ARM_EXYNOS_CPUIDLE
@@ -99,17 +90,6 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
 	return 1;
 }
 
-/*
- * exynos_map_io
- *
- * register the standard cpu IO areas
- */
-static void __init exynos_map_io(void)
-{
-	if (soc_is_exynos4())
-		iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-}
-
 static void __init exynos_init_io(void)
 {
 	debug_ll_io_init();
@@ -118,8 +98,6 @@ static void __init exynos_init_io(void)
 
 	/* detect cpu id and rev. */
 	s5p_init_cpu(S5P_VA_CHIPID);
-
-	exynos_map_io();
 }
 
 /*
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 5fb0040..0eef407 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -18,6 +18,4 @@
 
 #define EXYNOS_PA_CHIPID		0x10000000
 
-#define EXYNOS4_PA_COREPERI		0x10500000
-
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index a5d6841..553d0d9 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -224,11 +224,6 @@ static void write_pen_release(int val)
 	sync_cache_w(&pen_release);
 }
 
-static void __iomem *scu_base_addr(void)
-{
-	return (void __iomem *)(S5P_VA_SCU);
-}
-
 static DEFINE_SPINLOCK(boot_lock);
 
 static void exynos_secondary_init(unsigned int cpu)
@@ -387,14 +382,23 @@ fail:
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
+	struct device_node *np;
+	void __iomem *scu_base;
 	int i;
 
 	exynos_sysram_init();
 
 	exynos_set_delayed_reset_assertion(true);
 
-	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
-		scu_enable(scu_base_addr());
+	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+		np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+		scu_base = of_iomap(np, 0);
+		if (scu_base) {
+			scu_enable(scu_base);
+			iounmap(scu_base);
+		}
+		of_node_put(np);
+	}
 
 	/*
 	 * Write the address of secondary startup into the
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 487295f..60e6827 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -18,6 +18,7 @@
 #include <linux/cpu_pm.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
 
@@ -26,8 +27,6 @@
 #include <asm/suspend.h>
 #include <asm/cacheflush.h>
 
-#include <mach/map.h>
-
 #include "common.h"
 
 static inline void __iomem *exynos_boot_vector_addr(void)
@@ -158,6 +157,8 @@ static int exynos_aftr_finisher(unsigned long flags)
 
 void exynos_enter_aftr(void)
 {
+	struct device_node *np;
+	void __iomem *scu_base;
 	unsigned int cpuid = smp_processor_id();
 
 	cpu_pm_enter();
@@ -177,7 +178,14 @@ void exynos_enter_aftr(void)
 	cpu_suspend(0, exynos_aftr_finisher);
 
 	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
-		scu_enable(S5P_VA_SCU);
+		np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+		scu_base = of_iomap(np, 0);
+		if (scu_base) {
+			scu_enable(scu_base);
+			iounmap(scu_base);
+		}
+		of_node_put(np);
+
 		if (call_firmware_op(resume) == -ENOSYS)
 			exynos_cpu_restore_register();
 	}
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index 06332f6..7ab7e67 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -34,8 +34,6 @@
 #include <asm/smp_scu.h>
 #include <asm/suspend.h>
 
-#include <mach/map.h>
-
 #include <plat/pm-common.h>
 
 #include "common.h"
@@ -453,6 +451,8 @@ static void exynos_pm_release_retention(void)
 
 static void exynos_pm_resume(void)
 {
+	struct device_node *np;
+	void __iomem *scu_base;
 	u32 cpuid = read_cpuid_part();
 
 	if (exynos_pm_central_resume())
@@ -461,8 +461,15 @@ static void exynos_pm_resume(void)
 	/* For release retention */
 	exynos_pm_release_retention();
 
-	if (cpuid == ARM_CPU_PART_CORTEX_A9)
-		scu_enable(S5P_VA_SCU);
+	if (cpuid == ARM_CPU_PART_CORTEX_A9) {
+		np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+		scu_base = of_iomap(np, 0);
+		if (scu_base) {
+			scu_enable(scu_base);
+			iounmap(scu_base);
+		}
+		of_node_put(np);
+	}
 
 	if (call_firmware_op(resume) == -ENOSYS
 	    && cpuid == ARM_CPU_PART_CORTEX_A9)
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
index 0fe2828..512ed1f 100644
--- a/arch/arm/plat-samsung/include/plat/map-s5p.h
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -15,10 +15,6 @@
 
 #define S5P_VA_CHIPID		S3C_ADDR(0x02000000)
 
-#define S5P_VA_COREPERI_BASE	S3C_ADDR(0x02800000)
-#define S5P_VA_COREPERI(x)	(S5P_VA_COREPERI_BASE + (x))
-#define S5P_VA_SCU		S5P_VA_COREPERI(0x0)
-
 #define VA_VIC(x)		(S3C_VA_IRQ + ((x) * 0x10000))
 #define VA_VIC0			VA_VIC(0)
 #define VA_VIC1			VA_VIC(1)
-- 
2.7.4

^ permalink raw reply related

* [PATCH 2/4] ARM: dts: exynos: Add SCU device node to exynos4.dtsi
From: Pankaj Dubey @ 2016-11-04  3:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478230764-13748-1-git-send-email-pankaj.dubey@samsung.com>

Exynos4 like other Cortex-A9 SoC's has a Snoop Control Unit(SCU)
and its SFR are used during SMP boot and S2R. Add SCU node to the device tree.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/boot/dts/exynos4.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 5f034eb..6865ca9 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -78,6 +78,11 @@
 		reg = <0x10000000 0x100>;
 	};
 
+	scu: snoop-control-unit at 10500000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0x10500000 0x2000>;
+	};
+
 	memory-controller at 12570000 {
 		compatible = "samsung,exynos4210-srom";
 		reg = <0x12570000 0x14>;
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/4] ARM: EXYNOS: Remove smp_init_cpus hook from platsmp.c
From: Pankaj Dubey @ 2016-11-04  3:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478230764-13748-1-git-send-email-pankaj.dubey@samsung.com>

We can safely remove exynos_smp_init_cpus() hook from mach-exynos/platsmp.c,
as all SMP platforms in mach-exynos can rely on DT for CPU core description
instead of determining number of cores from the SCU.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 98ffe1e..a5d6841 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -385,36 +385,6 @@ fail:
 	return pen_release != -1 ? ret : 0;
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-
-static void __init exynos_smp_init_cpus(void)
-{
-	void __iomem *scu_base = scu_base_addr();
-	unsigned int i, ncores;
-
-	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
-		ncores = scu_base ? scu_get_core_count(scu_base) : 1;
-	else
-		/*
-		 * CPU Nodes are passed thru DT and set_cpu_possible
-		 * is set by "arm_dt_init_cpu_maps".
-		 */
-		return;
-
-	/* sanity check */
-	if (ncores > nr_cpu_ids) {
-		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-			ncores, nr_cpu_ids);
-		ncores = nr_cpu_ids;
-	}
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
-}
-
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
 	int i;
@@ -479,7 +449,6 @@ static void exynos_cpu_die(unsigned int cpu)
 #endif /* CONFIG_HOTPLUG_CPU */
 
 const struct smp_operations exynos_smp_ops __initconst = {
-	.smp_init_cpus		= exynos_smp_init_cpus,
 	.smp_prepare_cpus	= exynos_smp_prepare_cpus,
 	.smp_secondary_init	= exynos_secondary_init,
 	.smp_boot_secondary	= exynos_boot_secondary,
-- 
2.7.4

^ permalink raw reply related

* [PATCH 0/4] Add SCU device node support for Exynos4
From: Pankaj Dubey @ 2016-11-04  3:39 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series does some cleanup for Exynos4 SoC based boards.
We are currently statically mapping SCU SFRs in mach-exynos/exynos.c
which can be avoided and related dependencies can be removed by introduction
of SCU device node. 
  
This patch series is tested on Exynos4210 based Origen board for SMP boot.

Pankaj Dubey (4):
  ARM: EXYNOS: Remove smp_init_cpus hook from platsmp.c
  ARM: dts: exynos: Add SCU device node to exynos4.dtsi
  ARM: EXYNOS: Remove static mapping of SCU SFR
  ARM: EXYNOS: Remove unused soc_is_exynos{4,5}

 arch/arm/boot/dts/exynos4.dtsi               |  5 +++
 arch/arm/mach-exynos/common.h                |  5 ---
 arch/arm/mach-exynos/exynos.c                | 22 -------------
 arch/arm/mach-exynos/include/mach/map.h      |  2 --
 arch/arm/mach-exynos/platsmp.c               | 49 +++++++---------------------
 arch/arm/mach-exynos/pm.c                    | 14 ++++++--
 arch/arm/mach-exynos/suspend.c               | 15 ++++++---
 arch/arm/plat-samsung/include/plat/map-s5p.h |  4 ---
 8 files changed, 38 insertions(+), 78 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH] mm: hugetlb: rename some allocation functions
From: Huang Shijie @ 2016-11-04  3:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478141499-13825-2-git-send-email-shijie.huang@arm.com>

After a future patch, the __alloc_buddy_huge_page() will not necessarily
use the buddy allocator.

So this patch removes the "buddy" from these functions:
	__alloc_buddy_huge_page -> __alloc_huge_page
	__alloc_buddy_huge_page_no_mpol -> __alloc_huge_page_no_mpol
	__alloc_buddy_huge_page_with_mpol -> __alloc_huge_page_with_mpol

This patch makes preparation for the later patch.

Acked-by: Steve Capper <steve.capper@arm.com>
Signed-off-by: Huang Shijie <shijie.huang@arm.com>
---

Fix the build error in the x86 platform.

---
 mm/hugetlb.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 32594f1..9fdfc24 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1163,6 +1163,10 @@ static inline void destroy_compound_gigantic_page(struct page *page,
 						unsigned int order) { }
 static inline int alloc_fresh_gigantic_page(struct hstate *h,
 					nodemask_t *nodes_allowed) { return 0; }
+static struct page *alloc_gigantic_page(int nid, unsigned int order)
+{
+	return NULL;
+}
 #endif
 
 static void update_and_free_page(struct hstate *h, struct page *page)
@@ -1568,7 +1572,7 @@ static struct page *__hugetlb_alloc_buddy_huge_page(struct hstate *h,
  * For (2), we ignore 'vma' and 'addr' and use 'nid' exclusively. This
  * implies that memory policies will not be taken in to account.
  */
-static struct page *__alloc_buddy_huge_page(struct hstate *h,
+static struct page *__alloc_huge_page(struct hstate *h,
 		struct vm_area_struct *vma, unsigned long addr, int nid)
 {
 	struct page *page;
@@ -1649,21 +1653,21 @@ static struct page *__alloc_buddy_huge_page(struct hstate *h,
  * anywhere.
  */
 static
-struct page *__alloc_buddy_huge_page_no_mpol(struct hstate *h, int nid)
+struct page *__alloc_huge_page_no_mpol(struct hstate *h, int nid)
 {
 	unsigned long addr = -1;
 
-	return __alloc_buddy_huge_page(h, NULL, addr, nid);
+	return __alloc_huge_page(h, NULL, addr, nid);
 }
 
 /*
  * Use the VMA's mpolicy to allocate a huge page from the buddy.
  */
 static
-struct page *__alloc_buddy_huge_page_with_mpol(struct hstate *h,
+struct page *__alloc_huge_page_with_mpol(struct hstate *h,
 		struct vm_area_struct *vma, unsigned long addr)
 {
-	return __alloc_buddy_huge_page(h, vma, addr, NUMA_NO_NODE);
+	return __alloc_huge_page(h, vma, addr, NUMA_NO_NODE);
 }
 
 /*
@@ -1681,7 +1685,7 @@ struct page *alloc_huge_page_node(struct hstate *h, int nid)
 	spin_unlock(&hugetlb_lock);
 
 	if (!page)
-		page = __alloc_buddy_huge_page_no_mpol(h, nid);
+		page = __alloc_huge_page_no_mpol(h, nid);
 
 	return page;
 }
@@ -1711,7 +1715,7 @@ static int gather_surplus_pages(struct hstate *h, int delta)
 retry:
 	spin_unlock(&hugetlb_lock);
 	for (i = 0; i < needed; i++) {
-		page = __alloc_buddy_huge_page_no_mpol(h, NUMA_NO_NODE);
+		page = __alloc_huge_page_no_mpol(h, NUMA_NO_NODE);
 		if (!page) {
 			alloc_ok = false;
 			break;
@@ -1963,7 +1967,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
 	page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve, gbl_chg);
 	if (!page) {
 		spin_unlock(&hugetlb_lock);
-		page = __alloc_buddy_huge_page_with_mpol(h, vma, addr);
+		page = __alloc_huge_page_with_mpol(h, vma, addr);
 		if (!page)
 			goto out_uncharge_cgroup;
 		if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) {
@@ -2221,7 +2225,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
 	 * First take pages out of surplus state.  Then make up the
 	 * remaining difference by allocating fresh huge pages.
 	 *
-	 * We might race with __alloc_buddy_huge_page() here and be unable
+	 * We might race with __alloc_huge_page() here and be unable
 	 * to convert a surplus huge page to a normal huge page. That is
 	 * not critical, though, it just means the overall size of the
 	 * pool might be one hugepage larger than it needs to be, but
@@ -2267,7 +2271,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
 	 * By placing pages into the surplus state independent of the
 	 * overcommit value, we are allowing the surplus pool size to
 	 * exceed overcommit. There are few sane options here. Since
-	 * __alloc_buddy_huge_page() is checking the global counter,
+	 * __alloc_huge_page() is checking the global counter,
 	 * though, we'll note that we're not allowed to exceed surplus
 	 * and won't grow the pool anywhere else. Not until one of the
 	 * sysctls are changed, or the surplus pages go out of use.
-- 
2.5.5

^ permalink raw reply related

* [PATCH v27 0/9] arm64: add kdump support
From: AKASHI Takahiro @ 2016-11-04  3:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161102044959.11954-1-takahiro.akashi@linaro.org>

For easier testing, I pushed my patches to:
https://git.linaro.org/people/takahiro.akashi/linux-aarch64.git arm64/kdump
https://git.linaro.org/people/takahiro.akashi/kexec-tools.git arm64/kdump

If anybody tries my patches, please let me know the result.
(Pratyush, thank you for your test.)

Thanks,
-Takahiro AKASHI

On Wed, Nov 02, 2016 at 01:49:59PM +0900, AKASHI Takahiro wrote:
>     v27-specific note: In this version, the change made in v26 was reverted
>     because I've got a comment that /reserved-memory DT property should
>     not be used on UEFI/ACPI systems, even though it is workable under
>     the current implementation. I've also confirmed that Rob doesn't argue
>     any more against using "linux,usable-memory-range".
>     So v27 is essentially the same as v25.
> 
> This patch series adds kdump support on arm64.
> 
> To load a crash-dump kernel to the systems, a series of patches to
> kexec-tools[1] are also needed. Please use the latest one, v4 [2].
> 
> To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
>   - crash utility (v7.1.6 or later) [3]
> 
> 
> [1] https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
> [1] http://lists.infradead.org/pipermail/kexec/2016-November/017555.html
> [2] https://github.com/crash-utility/crash.git
> 
> Changes for v27 (Nov 2, 2016)
>   o rebased to Linux-v4.9-rc3
>   o revert v26 change, i.e. revive "linux,usable-memory-range" property
>     (patch #2/#3, updating patch #9)
>   o minor fixes per review comments (patch #3/#4/#6/#8)
>   o re-order patches and improve commit messages for readability
> 
> Changes for v26 (Sep 7, 2016):
>   o Use /reserved-memory instead of "linux,usable-memory-range" property
>     (dropping v25's patch#2 and #3, updating ex-patch#9.)
> 
> Changes for v25 (Aug 29, 2016):
>   o Rebase to Linux-4.8-rc4
>   o Use memremap() instead of ioremap_cache() [patch#5]
> 
> Changes for v24 (Aug 9, 2016):
>   o Rebase to Linux-4.8-rc1
>   o Update descriptions about newly added DT proerties
> 
> Changes for v23 (July 26, 2016):
> 
>   o Move memblock_reserve() to a single place in reserve_crashkernel()
>   o Use  cpu_park_loop() in ipi_cpu_crash_stop()
>   o Always enforce ARCH_LOW_ADDRESS_LIMIT to the memory range of crash kernel
>   o Re-implement fdt_enforce_memory_region() to remove non-reserve regions
>     (for ACPI) from usable memory at crash kernel
> 
> Changes for v22 (July 12, 2016):
> 
>   o Export "crashkernel-base" and "crashkernel-size" via device-tree,
>     and add some descriptions about them in chosen.txt
>   o Rename "usable-memory" to "usable-memory-range" to avoid inconsistency
>     with powerpc's "usable-memory"
>   o Make cosmetic changes regarding "ifdef" usage
>   o Correct some wordings in kdump.txt
> 
> Changes for v21 (July 6, 2016):
> 
>   o Remove kexec patches.
>   o Rebase to arm64's for-next/core (Linux-4.7-rc4 based).
>   o Clarify the description about kvm in kdump.txt.
> 
> See the following link [3] for older changes:
> [3]  http://lists.infradead.org/pipermail/linux-arm-kernel/2016-June/438780.html
> 
> AKASHI Takahiro (8):
>   memblock: add memblock_cap_memory_range()
>   arm64: limit memory regions based on DT property, usable-memory-range
>   arm64: kdump: reserve memory for crash dump kernel
>   arm64: kdump: implement machine_crash_shutdown()
>   arm64: kdump: add VMCOREINFO's for user-space tools
>   arm64: kdump: provide /proc/vmcore file
>   arm64: kdump: enable kdump in defconfig
>   Documentation: kdump: describe arm64 port
> 
> James Morse (1):
>   Documentation: dt: chosen properties for arm64 kdump
> 
>  Documentation/devicetree/bindings/chosen.txt |  50 +++++++
>  Documentation/kdump/kdump.txt                |  16 ++-
>  arch/arm64/Kconfig                           |  11 ++
>  arch/arm64/configs/defconfig                 |   1 +
>  arch/arm64/include/asm/hardirq.h             |   2 +-
>  arch/arm64/include/asm/kexec.h               |  42 +++++-
>  arch/arm64/include/asm/smp.h                 |   2 +
>  arch/arm64/kernel/Makefile                   |   1 +
>  arch/arm64/kernel/crash_dump.c               |  71 ++++++++++
>  arch/arm64/kernel/machine_kexec.c            |  67 ++++++++-
>  arch/arm64/kernel/setup.c                    |   7 +-
>  arch/arm64/kernel/smp.c                      |  63 +++++++++
>  arch/arm64/mm/init.c                         | 199 +++++++++++++++++++++++++++
>  include/linux/memblock.h                     |   1 +
>  mm/memblock.c                                |  28 ++++
>  15 files changed, 554 insertions(+), 7 deletions(-)
>  create mode 100644 arch/arm64/kernel/crash_dump.c
> 
> -- 
> 2.10.0
> 

^ permalink raw reply

* [PATCH 1/2] arm64: hugetlb: remove the wrong pmd check in find_num_contig()
From: Huang Shijie @ 2016-11-04  2:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161104001616.ssjbemliorxi6evl@localhost>

On Thu, Nov 03, 2016 at 06:16:16PM -0600, Catalin Marinas wrote:
> On Thu, Nov 03, 2016 at 10:27:38AM +0800, Huang Shijie wrote:
> > diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> > index 2e49bd2..4811ef1 100644
> > --- a/arch/arm64/mm/hugetlbpage.c
> > +++ b/arch/arm64/mm/hugetlbpage.c
> > @@ -61,10 +61,6 @@ static int find_num_contig(struct mm_struct *mm, unsigned long addr,
> >  		return 1;
> >  	}
> >  	pmd = pmd_offset(pud, addr);
> > -	if (!pmd_present(*pmd)) {
> > -		VM_BUG_ON(!pmd_present(*pmd));
> > -		return 1;
> > -	}
> >  	if ((pte_t *)pmd == ptep) {
> >  		*pgsize = PMD_SIZE;
> >  		return CONT_PMDS;
> 
> BTW, for the !pud_present() and !pgd_present() cases, shouldn't
The kernel will not call the find_num_contig() if the PGD/PUD are empty.
Please see the code in the hugetlb_fault().

   ------------------------------------------------------
	ptep = huge_pte_offset(mm, address);
	if (ptep) {
	    ...............................
	} else {
		ptep = huge_pte_alloc(mm, address, huge_page_size(h));
		if (!ptep)
			return VM_FAULT_OOM;
	}
   ------------------------------------------------------


Thanks
Huang Shijie
> find_num_contig() actually return 0? These are more likely real bugs, so
> no point in setting the huge pte.

^ permalink raw reply

* [PATCH 3/6] clk: rockchip: add clock controller for rk1108
From: Shawn Lin @ 2016-11-04  2:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478176713-12066-1-git-send-email-andy.yan@rock-chips.com>

Hi Andy,

On 2016/11/3 20:38, Andy Yan wrote:
> From: Shawn Lin <shawn.lin@rock-chips.com>
>
> Add the clock tree definition and driver for rk1108 SoC.
>

We should spilt out another patch for adding clock/rst ID
as it should be in a shared branch. :)

You could respin it after Heiko reviews the other parts of
your patchset.

> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
> ---
>
>  drivers/clk/rockchip/Makefile          |   1 +
>  drivers/clk/rockchip/clk-rk1108.c      | 463 +++++++++++++++++++++++++++++++++
>  drivers/clk/rockchip/clk.h             |  14 +
>  include/dt-bindings/clock/rk1108-cru.h | 308 ++++++++++++++++++++++
>  4 files changed, 786 insertions(+)
>  create mode 100644 drivers/clk/rockchip/clk-rk1108.c
>  create mode 100644 include/dt-bindings/clock/rk1108-cru.h
>
> diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> index b5f2c8e..16e098c 100644
> --- a/drivers/clk/rockchip/Makefile
> +++ b/drivers/clk/rockchip/Makefile
> @@ -11,6 +11,7 @@ obj-y	+= clk-mmc-phase.o
>  obj-y	+= clk-ddr.o
>  obj-$(CONFIG_RESET_CONTROLLER)	+= softrst.o
>
> +obj-y	+= clk-rk1108.o
>  obj-y	+= clk-rk3036.o
>  obj-y	+= clk-rk3188.o
>  obj-y	+= clk-rk3228.o
> diff --git a/drivers/clk/rockchip/clk-rk1108.c b/drivers/clk/rockchip/clk-rk1108.c
> new file mode 100644
> index 0000000..eafc623
> --- /dev/null
> +++ b/drivers/clk/rockchip/clk-rk1108.c
> @@ -0,0 +1,463 @@
> +/*
> + * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
> + * Author: Shawn Lin <shawn.lin@rock-chips.com>
> + *         Andy Yan <andy.yan@rock-chips.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/syscore_ops.h>
> +#include <dt-bindings/clock/rk1108-cru.h>
> +#include "clk.h"
> +
> +#define RK1108_GRF_SOC_STATUS0	0x480
> +
> +enum rk1108_plls {
> +	apll, dpll, gpll,
> +};
> +
> +static struct rockchip_pll_rate_table rk1108_pll_rates[] = {
> +	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
> +	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
> +	RK3036_PLL_RATE( 594000000, 2, 99, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
> +	RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
> +	RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
> +	RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
> +	RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
> +	RK3036_PLL_RATE(  96000000, 1, 64, 4, 4, 1, 0),
> +	{ /* sentinel */ },
> +};
> +
> +
> +#define RK1108_DIV_CORE_MASK		0xf
> +#define RK1108_DIV_CORE_SHIFT		4
> +
> +#define RK1108_CLKSEL0(_core_peri_div)					\
> +	{									\
> +		.reg = RK1108_CLKSEL_CON(1),					\
> +		.val = HIWORD_UPDATE(_core_peri_div, RK1108_DIV_CORE_MASK,	\
> +				RK1108_DIV_CORE_SHIFT)				\
> +	}
> +
> +#define RK1108_CPUCLK_RATE(_prate, _core_peri_div)			\
> +	{								\
> +		.prate = _prate,					\
> +		.divs = {						\
> +			RK1108_CLKSEL0(_core_peri_div),		\
> +		},							\
> +	}
> +
> +static struct rockchip_cpuclk_rate_table rk1108_cpuclk_rates[] __initdata = {
> +	RK1108_CPUCLK_RATE(816000000, 4),
> +	RK1108_CPUCLK_RATE(600000000, 4),
> +	RK1108_CPUCLK_RATE(312000000, 4),
> +};
> +
> +static const struct rockchip_cpuclk_reg_data rk1108_cpuclk_data = {
> +	.core_reg = RK1108_CLKSEL_CON(0),
> +	.div_core_shift = 0,
> +	.div_core_mask = 0x1f,
> +	.mux_core_alt = 1,
> +	.mux_core_main = 0,
> +	.mux_core_shift = 8,
> +	.mux_core_mask = 0x1,
> +};
> +
> +PNAME(mux_pll_p)		= { "xin24m", "xin24m"};
> +
> +PNAME(mux_ddrphy_p)		= { "dpll_ddr", "gpll_ddr", "apll_ddr" };
> +PNAME(mux_armclk_p)		= { "apll_core", "gpll_core", "dpll_core" };
> +PNAME(mux_pmu_1f)		= { "xin24m", "pmu_24m"};
> +PNAME(mux_usb480m_phy_p)	= { "usb480m_phy0", "usb480m_phy1" };
> +PNAME(mux_usb480m_p)		= { "usb480m_phy", "xin24m" };
> +PNAME(mux_hdmiphy_p)		= { "hdmiphy_phy", "pclk_top_pre", "xin24m" };
> +
> +PNAME(mux_pll_src_4plls_p)	= { "dpll", "hdmiphy", "gpll", "usb480m" };
> +PNAME(mux_pll_src_3plls_p)	= { "apll", "gpll", "dpll" };
> +PNAME(mux_pll_src_2plls_p)	= { "dpll", "gpll" };
> +
> +PNAME(mux_aclk_peri_src_p)	= { "aclk_peri_src_dpll", "aclk_peri_src_gpll" };
> +PNAME(mux_aclk_bus_src_p)	= { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" };
> +
> +PNAME(mux_mmc_src_p)		= { "dpll", "gpll", "xin24m", "usb480m" };
> +PNAME(mux_pll_src_dpll_gpll_usb480m_p)	= { "dpll", "gpll", "usb480m" };
> +
> +
> +PNAME(mux_uart0_p)		= { "uart0_src", "uart0_frac", "xin24m" };
> +PNAME(mux_uart1_p)		= { "uart1_src", "uart1_frac", "xin24m" };
> +PNAME(mux_uart2_p)		= { "uart2_src", "uart2_frac", "xin24m" };
> +
> +
> +static struct rockchip_pll_clock rk1108_pll_clks[] __initdata = {
> +	[apll] = PLL(pll_rk3399, RK1108_APLL_ID, "apll", mux_pll_p, 0, RK1108_PLL_CON(0),
> +		     RK1108_PLL_CON(3), 8, 31, 0, rk1108_pll_rates),
> +	[dpll] = PLL(pll_rk3399, RK1108_DPLL_ID, "dpll", mux_pll_p, 0, RK1108_PLL_CON(8),
> +		     RK1108_PLL_CON(11), 8, 31, 0, NULL),
> +	[gpll] = PLL(pll_rk3399, RK1108_GPLL_ID, "gpll", mux_pll_p, 0, RK1108_PLL_CON(16),
> +		     RK1108_PLL_CON(19), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk1108_pll_rates),
> +};
> +
> +#define MFLAGS CLK_MUX_HIWORD_MASK
> +#define DFLAGS CLK_DIVIDER_HIWORD_MASK
> +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
> +
> +
> +static struct rockchip_clk_branch rk1108_uart0_fracmux __initdata =
> +	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
> +			RK1108_CLKSEL_CON(13), 8, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk1108_uart1_fracmux __initdata =
> +	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
> +			RK1108_CLKSEL_CON(14), 8, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk1108_uart2_fracmux __initdata =
> +	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
> +			RK1108_CLKSEL_CON(15), 8, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk1108_clk_branches[] __initdata = {
> +	/*
> +	 * Clock-Architecture Diagram 2
> +	 */
> +
> +	/* PD_CORE */
> +	GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(0), 1, GFLAGS),
> +	GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(0), 0, GFLAGS),
> +	GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(0), 2, GFLAGS),
> +	COMPOSITE_NOMUX(0, "pclken_dbg", "armclk", CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(1), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK1108_CLKGATE_CON(0), 5, GFLAGS),
> +	COMPOSITE_NOMUX(ACLK_ENMCORE, "aclkenm_core", "armclk", CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(1), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK1108_CLKGATE_CON(0), 4, GFLAGS),
> +	GATE(ACLK_CORE, "aclk_core", "aclkenm_core", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(11), 0, GFLAGS),
> +	GATE(0, "pclk_dbg", "pclken_dbg", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(11), 1, GFLAGS),
> +
> +	/* PD_RKVENC */
> +
> +	/* PD_RKVDEC */
> +
> +	/* PD_PMU_wrapper */
> +	COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(38), 0, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(8), 12, GFLAGS),
> +	GATE(0, "pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(10), 0, GFLAGS),
> +	GATE(0, "intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(10), 1, GFLAGS),
> +	GATE(0, "gpio0_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(10), 2, GFLAGS),
> +	GATE(0, "pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(10), 3, GFLAGS),
> +	GATE(0, "pmu_noc", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(10), 4, GFLAGS),
> +	GATE(0, "i2c0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(10), 5, GFLAGS),
> +	GATE(0, "pwm0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(10), 6, GFLAGS),
> +	COMPOSITE(0, "pwm0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(8), 15, GFLAGS),
> +	COMPOSITE(0, "i2c0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(8), 14, GFLAGS),
> +	GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(8), 13, GFLAGS),
> +
> +
> +
> +	/*
> +	 * Clock-Architecture Diagram 4
> +	 */
> +	COMPOSITE(0, "aclk_vio0_2wrap_occ", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(6), 0, GFLAGS),
> +	GATE(0, "aclk_vio0_pre", "aclk_vio0_2wrap_occ", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(17), 0, GFLAGS),
> +	COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0,
> +			RK1108_CLKSEL_CON(29), 0, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(7), 2, GFLAGS),
> +	COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0,
> +			RK1108_CLKSEL_CON(29), 8, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(7), 3, GFLAGS),
> +
> +
> +	/*
> +	 * Clock-Architecture Diagram 5
> +	 */
> +
> +	/* PD_BUS */
> +	GATE(0, "aclk_bus_src_gpll", "gpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 0, GFLAGS),
> +	GATE(0, "aclk_bus_src_apll", "apll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 1, GFLAGS),
> +	GATE(0, "aclk_bus_src_dpll", "dpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 2, GFLAGS),
> +	COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0,
> +			RK1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS),
> +	COMPOSITE_NOMUX(0, "hclk_bus_pre", "aclk_bus_2wrap_occ", 0,
> +			RK1108_CLKSEL_CON(3), 0, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(1), 4, GFLAGS),
> +	COMPOSITE_NOMUX(0, "pclken_bus", "aclk_bus_2wrap_occ", 0,
> +			RK1108_CLKSEL_CON(3), 8, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(1), 5, GFLAGS),
> +	GATE(0, "pclk_bus_pre", "pclken_bus", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 6, GFLAGS),
> +	GATE(0, "pclk_top_pre", "pclken_bus", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 7, GFLAGS),
> +	GATE(0, "pclk_ddr_pre", "pclken_bus", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 8, GFLAGS),
> +	GATE(0, "clk_timer0", "mux_pll_p", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 9, GFLAGS),
> +	GATE(0, "clk_timer1", "mux_pll_p", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(1), 10, GFLAGS),
> +	GATE(0, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 4, GFLAGS),
> +
> +	COMPOSITE(0, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(3), 1, GFLAGS),
> +	COMPOSITE(0, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(3), 3, GFLAGS),
> +	COMPOSITE(0, "uart21_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(3), 5, GFLAGS),
> +
> +	COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
> +			RK1108_CLKSEL_CON(16), 0,
> +			RK1108_CLKGATE_CON(3), 2, GFLAGS,
> +			&rk1108_uart0_fracmux),
> +	COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
> +			RK1108_CLKSEL_CON(17), 0,
> +			RK1108_CLKGATE_CON(3), 4, GFLAGS,
> +			&rk1108_uart1_fracmux),
> +	COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
> +			RK1108_CLKSEL_CON(18), 0,
> +			RK1108_CLKGATE_CON(3), 6, GFLAGS,
> +			&rk1108_uart2_fracmux),
> +	GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 10, GFLAGS),
> +	GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 11, GFLAGS),
> +	GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 12, GFLAGS),
> +
> +
> +	COMPOSITE(0, "clk_i2c1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(19), 15, 2, MFLAGS, 8, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(3), 7, GFLAGS),
> +	COMPOSITE(0, "clk_i2c2", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(20), 7, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(3), 8, GFLAGS),
> +	COMPOSITE(0, "clk_i2c3", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(20), 15, 2, MFLAGS, 8, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(3), 9, GFLAGS),
> +	GATE(0, "pclk_i2c1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 0, GFLAGS),
> +	GATE(0, "pclk_i2c2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 1, GFLAGS),
> +	GATE(0, "pclk_i2c3", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 2, GFLAGS),
> +	COMPOSITE(0, "clk_pwm1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(3), 10, GFLAGS),
> +	GATE(0, "pclk_pwm1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 6, GFLAGS),
> +	GATE(0, "pclk_wdt", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 3, GFLAGS),
> +	GATE(0, "pclk_gpio1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 7, GFLAGS),
> +	GATE(0, "pclk_gpio2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 8, GFLAGS),
> +	GATE(0, "pclk_gpio3", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(13), 9, GFLAGS),
> +
> +	GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(14), 0, GFLAGS),
> +
> +	GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0,
> +	     RK1108_CLKGATE_CON(12), 2, GFLAGS),
> +	GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(12), 3, GFLAGS),
> +	GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(12), 1, GFLAGS),
> +
> +	/* PD_DDR */
> +	GATE(0, "apll_ddr", "apll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(0), 8, GFLAGS),
> +	GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(0), 9, GFLAGS),
> +	GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(0), 10, GFLAGS),
> +	COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
> +			RK1108_CLKGATE_CON(10), 9, GFLAGS),
> +	GATE(0, "ddrupctl", "ddrphy_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(12), 4, GFLAGS),
> +	GATE(0, "ddrc", "ddrphy", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(12), 5, GFLAGS),
> +	GATE(0, "ddrmon", "ddrphy_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(12), 6, GFLAGS),
> +	GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(0), 11, GFLAGS),
> +
> +	/*
> +	 * Clock-Architecture Diagram 6
> +	 */
> +
> +	/* PD_PERI */
> +	COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0,
> +			RK1108_CLKSEL_CON(23), 10, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(4), 5, GFLAGS),
> +	GATE(0, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(15), 13, GFLAGS),
> +	COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0,
> +			RK1108_CLKSEL_CON(23), 5, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(4), 4, GFLAGS),
> +	GATE(0, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(15), 12, GFLAGS),
> +
> +	GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(4), 1, GFLAGS),
> +	GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED,
> +			RK1108_CLKGATE_CON(4), 2, GFLAGS),
> +	COMPOSITE(0, "aclk_periph", mux_aclk_peri_src_p, CLK_IGNORE_UNUSED,
> +			RK1108_CLKSEL_CON(23), 15, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(15), 11, GFLAGS),
> +
> +	COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0,
> +			RK1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS,
> +			RK1108_CLKGATE_CON(5), 0, GFLAGS),
> +
> +	COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
> +			RK1108_CLKSEL_CON(25), 10, 2, MFLAGS,
> +			RK1108_CLKGATE_CON(5), 2, GFLAGS),
> +	DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
> +			RK1108_CLKSEL_CON(26), 0, 8, DFLAGS),
> +
> +	COMPOSITE_NODIV(0, "sclk_emmc_src", mux_mmc_src_p, 0,
> +			RK1108_CLKSEL_CON(25), 12, 2, MFLAGS,
> +			RK1108_CLKGATE_CON(5), 1, GFLAGS),
> +	DIV(SCLK_EMMC, "sclk_emmc", "sclk_emmc_src", 0,
> +			RK2928_CLKSEL_CON(26), 8, 8, DFLAGS),
> +	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 0, GFLAGS),
> +	GATE(HCLK_SDIO, "hclk_sdio", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 1, GFLAGS),
> +	GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 2, GFLAGS),
> +
> +	COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0,
> +			RK1108_CLKSEL_CON(27), 14, 2, MFLAGS, 8, 5, DFLAGS,
> +			RK1108_CLKGATE_CON(5), 3, GFLAGS),
> +	GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 3, GFLAGS),
> +
> +	COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0,
> +			RK1108_CLKSEL_CON(27), 7, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK1108_CLKGATE_CON(5), 4, GFLAGS),
> +	GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 10, GFLAGS),
> +	MMC(SCLK_SDMMC_DRV,    "sdmmc_drv",    "sclk_sdmmc", RK1108_SDMMC_CON0, 1),
> +	MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK1108_SDMMC_CON1, 1),
> +
> +	MMC(SCLK_SDIO_DRV,     "sdio_drv",     "sclk_sdio",  RK1108_SDIO_CON0,  1),
> +	MMC(SCLK_SDIO_SAMPLE,  "sdio_sample",  "sclk_sdio",  RK1108_SDIO_CON1,  1),
> +
> +	MMC(SCLK_EMMC_DRV,     "emmc_drv",     "sclk_emmc",  RK1108_EMMC_CON0,  1),
> +	MMC(SCLK_EMMC_SAMPLE,  "emmc_sample",  "sclk_emmc",  RK1108_EMMC_CON1,  1),
> +};
> +
> +static const char *const rk1108_critical_clocks[] __initconst = {
> +	"aclk_core",
> +	"aclk_bus_src_gpll",
> +	"aclk_periph",
> +	"hclk_periph",
> +	"pclk_periph",
> +};
> +
> +static void __init rk1108_clk_init(struct device_node *np)
> +{
> +	struct rockchip_clk_provider *ctx;
> +	void __iomem *reg_base;
> +
> +	reg_base = of_iomap(np, 0);
> +	if (!reg_base) {
> +		pr_err("%s: could not map cru region\n", __func__);
> +		return;
> +	}
> +
> +	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
> +	if (IS_ERR(ctx)) {
> +		pr_err("%s: rockchip clk init failed\n", __func__);
> +		iounmap(reg_base);
> +		return;
> +	}
> +
> +	rockchip_clk_register_plls(ctx, rk1108_pll_clks,
> +				   ARRAY_SIZE(rk1108_pll_clks),
> +				   RK1108_GRF_SOC_STATUS0);
> +	rockchip_clk_register_branches(ctx, rk1108_clk_branches,
> +				  ARRAY_SIZE(rk1108_clk_branches));
> +	rockchip_clk_protect_critical(rk1108_critical_clocks,
> +				      ARRAY_SIZE(rk1108_critical_clocks));
> +
> +	rockchip_clk_register_armclk(ctx, RK1108_ARMCLK, "armclk",
> +			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
> +			&rk1108_cpuclk_data, rk1108_cpuclk_rates,
> +			ARRAY_SIZE(rk1108_cpuclk_rates));
> +
> +	rockchip_register_softrst(np, 13, reg_base + RK1108_SOFTRST_CON(0),
> +				  ROCKCHIP_SOFTRST_HIWORD_MASK);
> +
> +	rockchip_register_restart_notifier(ctx, RK1108_GLB_SRST_FST, NULL);
> +
> +	rockchip_clk_of_add_provider(np, ctx);
> +}
> +CLK_OF_DECLARE(rk1108_cru, "rockchip,rk1108-cru", rk1108_clk_init);
> diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
> index 1653edd..90c580a 100644
> --- a/drivers/clk/rockchip/clk.h
> +++ b/drivers/clk/rockchip/clk.h
> @@ -34,6 +34,20 @@ struct clk;
>  #define HIWORD_UPDATE(val, mask, shift) \
>  		((val) << (shift) | (mask) << ((shift) + 16))
>
> +/* register positions shared by RK1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
> +#define RK1108_PLL_CON(x)		((x) * 0x4)
> +#define RK1108_CLKSEL_CON(x)		((x) * 0x4 + 0x60)
> +#define RK1108_CLKGATE_CON(x)		((x) * 0x4 + 0x120)
> +#define RK1108_SOFTRST_CON(x)		((x) * 0x4 + 0x180)
> +#define RK1108_GLB_SRST_FST		0x1c0
> +#define RK1108_GLB_SRST_SND		0x1c4
> +#define RK1108_SDMMC_CON0		0x1d8
> +#define RK1108_SDMMC_CON1		0x1dc
> +#define RK1108_SDIO_CON0		0x1e0
> +#define RK1108_SDIO_CON1		0x1e4
> +#define RK1108_EMMC_CON0		0x1e8
> +#define RK1108_EMMC_CON1		0x1ec
> +
>  #define RK2928_PLL_CON(x)		((x) * 0x4)
>  #define RK2928_MODE_CON		0x40
>  #define RK2928_CLKSEL_CON(x)	((x) * 0x4 + 0x44)
> diff --git a/include/dt-bindings/clock/rk1108-cru.h b/include/dt-bindings/clock/rk1108-cru.h
> new file mode 100644
> index 0000000..e731cc8
> --- /dev/null
> +++ b/include/dt-bindings/clock/rk1108-cru.h
> @@ -0,0 +1,308 @@
> +/*
> + * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
> + * Author:
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H
> +#define _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H
> +
> +/* pll id */
> +#define RK1108_APLL_ID			0
> +#define RK1108_DPLL_ID			1
> +#define RK1108_GPLL_ID			2
> +#define RK1108_ARMCLK			3
> +#define RK1108_END_PLL_ID		4
> +
> +/* sclk gates (special clocks) */
> +#define SCLK_SPI0			65
> +#define SCLK_NANDC			67
> +#define SCLK_SDMMC			68
> +#define SCLK_SDIO			69
> +#define SCLK_EMMC			71
> +#define SCLK_UART0			72
> +#define SCLK_UART1			73
> +#define SCLK_UART2			74
> +#define SCLK_I2S0			75
> +#define SCLK_I2S1			76
> +#define SCLK_I2S2			77
> +#define SCLK_TIMER0			78
> +#define SCLK_TIMER1			79
> +#define SCLK_SFC			80
> +#define SCLK_SDMMC_DRV			81
> +#define SCLK_SDIO_DRV			82
> +#define SCLK_EMMC_DRV			83
> +#define SCLK_SDMMC_SAMPLE		84
> +#define SCLK_SDIO_SAMPLE		85
> +#define SCLK_EMMC_SAMPLE		86
> +
> +/* aclk gates */
> +#define ACLK_DMAC			251
> +#define ACLK_PRE			252
> +#define ACLK_CORE			253
> +#define ACLK_ENMCORE			254
> +
> +/* pclk gates */
> +#define PCLK_GPIO1			321
> +#define PCLK_GPIO2			322
> +#define PCLK_GPIO3			323
> +#define PCLK_GRF			329
> +#define PCLK_I2C1			333
> +#define PCLK_I2C2			334
> +#define PCLK_I2C3			335
> +#define PCLK_SPI			338
> +#define PCLK_SFC			339
> +#define PCLK_UART0			341
> +#define PCLK_UART1			342
> +#define PCLK_UART2			343
> +#define PCLK_TSADC			344
> +#define PCLK_PWM			350
> +#define PCLK_TIMER			353
> +#define PCLK_PERI			363
> +
> +/* hclk gates */
> +#define HCLK_I2S0_8CH			442
> +#define HCLK_I2S1_8CH			443
> +#define HCLK_I2S2_2CH			444
> +#define HCLK_NANDC			453
> +#define HCLK_SDMMC			456
> +#define HCLK_SDIO			457
> +#define HCLK_EMMC			459
> +#define HCLK_PERI			478
> +#define HCLK_SFC			479
> +
> +#define CLK_NR_CLKS			(HCLK_SFC + 1)
> +
> +/* reset id */
> +#define SRST_CORE_PO_AD			0
> +#define SRST_CORE_AD			1
> +#define SRST_L2_AD			2
> +#define SRST_CPU_NIU_AD			3
> +#define SRST_CORE_PO			4
> +#define SRST_CORE			5
> +#define SRST_L2				6
> +#define RST_0RES7			7
> +#define SRST_CORE_DBG			8
> +#define PRST_DBG			9
> +#define RST_DAP				10
> +#define PRST_DBG_NIU			11
> +#define RST_0RES12			12
> +#define RST_0RES13			13
> +#define RST_0RES14			14
> +#define ARST_STRC_SYS_AD		15
> +
> +#define SRST_DDRPHY_CLKDIV		16
> +#define SRST_DDRPHY			17
> +#define PRST_DDRPHY			18
> +#define PRST_HDMIPHY			19
> +#define PRST_VDACPHY			20
> +#define PRST_VADCPHY			21
> +#define PRST_MIPI_CSI_PHY		22
> +#define PRST_MIPI_DSI_PHY		23
> +#define PRST_ACODEC			24
> +#define ARST_BUS_NIU			25
> +#define PRST_TOP_NIU			26
> +#define ARST_INTMEM			27
> +#define HRST_ROM			28
> +#define ARST_DMAC			29
> +#define SRST_MSCH_NIU			30
> +#define PRST_MSCH_NIU			31
> +
> +#define PRST_DDRUPCTL			32
> +#define NRST_DDRUPCTL			33
> +#define PRST_DDRMON			34
> +#define HRST_I2S0_8CH			35
> +#define MRST_I2S0_8CH			36
> +#define HRST_I2S1_2CH			37
> +#define MRST_IS21_2CH			38
> +#define HRST_I2S2_2CH			39
> +#define MRST_I2S2_2CH			40
> +#define HRST_CRYPTO			41
> +#define SRST_CRYPTO			42
> +#define PRST_SPI			43
> +#define SRST_SPI			44
> +#define PRST_UART0			45
> +#define PRST_UART1			46
> +#define PRST_UART2			47
> +
> +#define SRST_UART0			48
> +#define SRST_UART1			49
> +#define SRST_UART2			50
> +#define PRST_I2C1			51
> +#define PRST_I2C2			52
> +#define PRST_I2C3			53
> +#define SRST_I2C1			54
> +#define SRST_I2C2			55
> +#define SRST_I2C3			56
> +#define RST_3RES9			57
> +#define PRST_PWM1			58
> +#define RST_3RES11			59
> +#define SRST_PWM1			60
> +#define PRST_WDT			61
> +#define PRST_GPIO1			62
> +#define PRST_GPIO2			63
> +
> +#define PRST_GPIO3			64
> +#define PRST_GRF			65
> +#define PRST_EFUSE			66
> +#define PRST_EFUSE512			67
> +#define PRST_TIMER0			68
> +#define SRST_TIMER0			69
> +#define SRST_TIMER1			70
> +#define PRST_TSADC			71
> +#define SRST_TSADC			72
> +#define PRST_SARADC			73
> +#define SRST_SARADC			74
> +#define HRST_SYSBUS			75
> +#define PRST_USBGRF			76
> +#define RST_4RES13			77
> +#define RST_4RES14			78
> +#define RST_4RES15			79
> +
> +#define ARST_PERIPH_NIU			80
> +#define HRST_PERIPH_NIU			81
> +#define PRST_PERIPH_NIU			82
> +#define HRST_PERIPH			83
> +#define HRST_SDMMC			84
> +#define HRST_SDIO			85
> +#define HRST_EMMC			86
> +#define HRST_NANDC			87
> +#define NRST_NANDC			88
> +#define HRST_SFC			89
> +#define SRST_SFC			90
> +#define ARST_GMAC			91
> +#define HRST_OTG			92
> +#define SRST_OTG			93
> +#define SRST_OTG_ADP			94
> +#define HRST_HOST0			95
> +
> +#define HRST_HOST0_AUX			96
> +#define HRST_HOST0_ARB			97
> +#define SRST_HOST0_EHCIPHY		98
> +#define SRST_HOST0_UTMI			99
> +#define SRST_USBPOR			100
> +#define SRST_UTMI0			101
> +#define SRST_UTMI1			102
> +#define RST_6RES7			103
> +#define RST_6RES8			104
> +#define RST_6RES9			105
> +#define RST_6RES10			106
> +#define RST_6RES11			107
> +#define RST_6RES12			108
> +#define RST_6RES13			109
> +#define RST_6RES14			110
> +#define RST_6RES15			101
> +
> +#define ARST_VIO0_NIU			102
> +#define ARST_VIO1_NIU			103
> +#define HRST_VIO_NIU			104
> +#define PRST_VIO_NIU			105
> +#define ARST_VOP			106
> +#define HRST_VOP			107
> +#define DRST_VOP			108
> +#define ARST_IEP			109
> +#define HRST_IEP			110
> +#define ARST_RGA			111
> +#define HRST_RGA			112
> +#define SRST_RGA			113
> +#define PRST_CVBS			114
> +#define PRST_HDMI			115
> +#define SRST_HDMI			116
> +#define PRST_MIPI_DSI			117
> +
> +#define ARST_ISP_NIU			118
> +#define HRST_ISP_NIU			119
> +#define HRST_ISP			120
> +#define SRST_ISP			121
> +#define ARST_VIP0			122
> +#define HRST_VIP0			123
> +#define PRST_VIP0			124
> +#define ARST_VIP1			125
> +#define HRST_VIP1			126
> +#define PRST_VIP1			127
> +#define ARST_VIP2			128
> +#define HRST_VIP2			129
> +#define PRST_VIP2			120
> +#define ARST_VIP3			121
> +#define HRST_VIP3			122
> +#define PRST_VIP4			123
> +
> +#define PRST_CIF1TO4			124
> +#define SRST_CVBS_CLK			125
> +#define HRST_CVBS			126
> +#define RST_9RES3			127
> +#define RST_9RES4			128
> +#define RST_9RES5			129
> +#define RST_9RES6			130
> +#define RST_9RES7			131
> +#define RST_9RES8			132
> +#define RST_9RES9			133
> +#define RST_9RES10			134
> +#define RST_9RES11			134
> +#define RST_9RES12			136
> +#define RST_9RES13			137
> +#define RST_9RES14			138
> +#define RST_9RES15			139
> +
> +#define ARST_VPU_NIU			140
> +#define HRST_VPU_NIU			141
> +#define ARST_VPU			142
> +#define HRST_VPU			143
> +#define ARST_RKVDEC_NIU			144
> +#define HRST_RKVDEC_NIU			145
> +#define ARST_RKVDEC			146
> +#define HRST_RKVDEC			147
> +#define SRST_RKVDEC_CABAC		148
> +#define SRST_RKVDEC_CORE		149
> +#define ARST_RKVENC_NIU			150
> +#define HRST_RKVENC_NIU			151
> +#define ARST_RKVENC			152
> +#define HRST_RKVENC			153
> +#define SRST_RKVENC_CORE		154
> +#define RST_10RES15			155
> +
> +#define SRST_DSP_CORE			156
> +#define SRST_DSP_SYS			157
> +#define SRST_DSP_GLOBAL			158
> +#define SRST_DSP_OECM			159
> +#define PRST_DSP_IOP_NIU		160
> +#define ARST_DSP_EPP_NIU		161
> +#define ARST_DSP_EDP_NIU		162
> +#define PRST_DSP_DBG_NIU		163
> +#define PRST_DSP_CFG_NIU		164
> +#define PRST_DSP_GRF			165
> +#define PRST_DSP_MAILBOX		166
> +#define PRST_DSP_INTC			167
> +#define RST_11RES12			168
> +#define PRST_DSP_PFM_MON		169
> +#define SRST_DSP_PFM_MON		170
> +#define ARST_DSP_EDAP_NIU		171
> +
> +#define SRST_PMU			172
> +#define SRST_PMU_I2C0			173
> +#define PRST_PMU_I2C0			174
> +#define PRST_PMU_GPIO0			175
> +#define PRST_PMU_INTMEM			176
> +#define PRST_PMU_PWM0			177
> +#define SRST_PMU_PWM0			178
> +#define PRST_PMU_GRF			179
> +#define SRST_PMU_NIU			180
> +#define SRST_PMU_PVTM			181
> +#define RST_12RES10			182
> +#define RST_12RES11			183
> +#define ARST_DSP_EDP_PERF		184
> +#define ARST_DSP_EPP_PERF		185
> +#define RST_12RES114			186
> +#define RST_12RES15			187
> +
> +#endif /* _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H */
> +
>


-- 
Best Regards
Shawn Lin

^ permalink raw reply

* [PATCH 0/2] mm: fix the "counter.sh" failure for libhugetlbfs
From: Huang Shijie @ 2016-11-04  1:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0a660010-5083-476a-b2c5-88d822089000@infradead.org>

On Thu, Nov 03, 2016 at 10:22:39AM -0700, Randy Dunlap wrote:
> On 11/02/16 19:51, Huang Shijie wrote:
> > 
> > (2) The bug   
> >    After I tested the libhugetlbfs, I found the test case "counter.sh"
> >    will fail with the gigantic page (32M page in arm64 board).
> > 
> >    This patch set adds support for gigantic surplus hugetlb pages,
> >    allowing the counter.sh unit test to pass.   
> 
> Hi,
> Where is the counter.sh test? Where can I find it?
You can get the libhugetlbfs from:
   https://github.com/libhugetlbfs/libhugetlbfs.git

Use the "make func" to test it, but the default libhugetlbfs can not run
for the 32M page hugetlbfs, there are several bugs in it. I have an
extra patch set to fix the libhugetlbfs bugs. Maybe I can send them out
later.

But for the 2M page size, you can test the "counter.sh" with "make
func".

thanks
Huang Shijie

^ permalink raw reply

* [PATCH v2 06/14] ASoC: sun4i-codec: Add support for A31 playback through headphone output
From: Chen-Yu Tsai @ 2016-11-04  1:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103173602.zchyciwj66zdibc7@lukather>

On Fri, Nov 4, 2016 at 1:36 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Thu, Nov 03, 2016 at 03:55:48PM +0800, Chen-Yu Tsai wrote:
>> +/* headphone controls */
>> +static const char * const sun6i_codec_hp_src_enum_text[] = {
>> +     "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
>> +                         SUN6I_CODEC_OM_DACA_CTRL,
>> +                         SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
>> +                         SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
>> +                         sun6i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
>> +     SOC_DAPM_ENUM("Headphone Source Playback Route",
>> +                   sun6i_codec_hp_src_enum),
>> +};
>
> What is that route exactly? A muxer?

Yup. The following is part of the widgets list later in the code:

+       /* Headphone output path */
+       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
+                        SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src),

ChenYu

^ permalink raw reply

* [PATCH] clk: rockchip: fix some clocks' name to be more standard style
From: jay.xu @ 2016-11-04  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <44798035.VNVnDcOLnj@diego>

Hi Heiko and Shawn:

ok, I agree with you, and the root fix seems to fix it in the TRM first.
I'll feedback to TRM makers.

Thanks.

On 2016?11?03? 22:32, Heiko St?bner wrote:
> Am Donnerstag, 3. November 2016, 16:52:48 schrieb Shawn Lin:
>> On 2016/11/2 15:04, Jianqun Xu wrote:
>>> Fix aclk_emmcgrf to aclk_emmc_grf, and fix aclk_emmccore to be
>>> aclk_emmc_core.
>>
>> What is the standard style should be?
>>
>> TRM uses aclk_emmccore but not aclk_emmc_core, so should it be more
>> standrad to keep it as-is?
>
> I tend to agree with Shawn. While it looks like the missing "_" is some sort
> of mistake, we should strive to follow TRM naming, so grepping so it becomes
> easier to look for informations in these things in the TRM.
>
> Same reason for naming our regulators and pinctrl after the names used in
> device schematics, if available.
>
>
> Heiko
>
>
>

^ permalink raw reply

* [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching of bypass entries
From: Nipun Gupta @ 2016-11-04  0:27 UTC (permalink / raw)
  To: linux-arm-kernel

The SMTNMB_TLBEN in the Auxiliary Configuration Register (ACR) provides an
option to enable the updation of TLB in case of bypass transactions due to
no stream match in the stream match table. This reduces the latencies of
the subsequent transactions with the same stream-id which bypasses the SMMU.
This provides a significant performance benefit for certain networking
workloads.

With this change substantial performance improvement of ~9% is observed with
DPDK l3fwd application (http://dpdk.org/doc/guides/sample_app_ug/l3_forward.html)
on NXP's LS2088a platform.

Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
Changes for v2:
    - Incorporated Robin's comments on v1 related to
	Setting SMTNMB_TLBEN in ACR only for MMU-500 as ACR is implementation dependent
	Code comments and Naming convention

 drivers/iommu/arm-smmu.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index ce2a9d4..05901be 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -247,6 +247,7 @@ enum arm_smmu_s2cr_privcfg {
 #define ARM_MMU500_ACTLR_CPRE		(1 << 1)
 
 #define ARM_MMU500_ACR_CACHE_LOCK	(1 << 26)
+#define ARM_MMU500_ACR_SMTNMB_TLBEN	(1 << 8)
 
 #define CB_PAR_F			(1 << 0)
 
@@ -1569,16 +1570,22 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
 	for (i = 0; i < smmu->num_mapping_groups; ++i)
 		arm_smmu_write_sme(smmu, i);
 
-	/*
-	 * Before clearing ARM_MMU500_ACTLR_CPRE, need to
-	 * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
-	 * bit is only present in MMU-500r2 onwards.
-	 */
-	reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
-	major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
-	if ((smmu->model == ARM_MMU500) && (major >= 2)) {
+	if (smmu->model == ARM_MMU500) {
+		/*
+		 * Before clearing ARM_MMU500_ACTLR_CPRE, need to
+		 * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
+		 * bit is only present in MMU-500r2 onwards.
+		 */
+		reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
+		major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
 		reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR);
-		reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
+		if (major >= 2)
+			reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
+		/*
+		 * Allow unmatched Stream IDs to allocate bypass
+		 * TLB entries for reduced latency.
+		 */
+		reg |= ARM_MMU500_ACR_SMTNMB_TLBEN;
 		writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
 	}
 
-- 
1.9.1

^ permalink raw reply related


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